{"version":3,"file":"search-module-G2LPJzpV.js","sources":["../../../../node_modules/core-js/internals/validate-arguments-length.js","../../../../node_modules/core-js/modules/web.url-search-params.delete.js","../../../../node_modules/core-js/modules/web.url-search-params.has.js","../../../../node_modules/core-js/modules/web.url-search-params.size.js","../../../../src/main/js/navigation/global/components/search/searchMetrics.js","../../../../src/main/js/navigation/global/components/search/search.js","../../../../src/main/js/navigation/global/components/search/filterResults.js","../../../../src/main/js/navigation/global/components/search/constants.js","../../../../src/main/js/navigation/global/components/search/listboxUtil.js","../../../../src/main/js/navigation/global/components/search/suggest.js","../../../../src/main/js/navigation/global/components/search/recents.js","../../../../src/main/js/navigation/global/components/search/entry/main.js","../../../../src/main/js/navigation/global/components/search/entry/search-module.js"],"sourcesContent":["'use strict';\nvar $TypeError = TypeError;\n\nmodule.exports = function (passed, required) {\n if (passed < required) throw new $TypeError('Not enough arguments');\n return passed;\n};\n","'use strict';\nvar defineBuiltIn = require('../internals/define-built-in');\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar toString = require('../internals/to-string');\nvar validateArgumentsLength = require('../internals/validate-arguments-length');\n\nvar $URLSearchParams = URLSearchParams;\nvar URLSearchParamsPrototype = $URLSearchParams.prototype;\nvar append = uncurryThis(URLSearchParamsPrototype.append);\nvar $delete = uncurryThis(URLSearchParamsPrototype['delete']);\nvar forEach = uncurryThis(URLSearchParamsPrototype.forEach);\nvar push = uncurryThis([].push);\nvar params = new $URLSearchParams('a=1&a=2&b=3');\n\nparams['delete']('a', 1);\n// `undefined` case is a Chromium 117 bug\n// https://bugs.chromium.org/p/v8/issues/detail?id=14222\nparams['delete']('b', undefined);\n\nif (params + '' !== 'a=2') {\n defineBuiltIn(URLSearchParamsPrototype, 'delete', function (name /* , value */) {\n var length = arguments.length;\n var $value = length < 2 ? undefined : arguments[1];\n if (length && $value === undefined) return $delete(this, name);\n var entries = [];\n forEach(this, function (v, k) { // also validates `this`\n push(entries, { key: k, value: v });\n });\n validateArgumentsLength(length, 1);\n var key = toString(name);\n var value = toString($value);\n var index = 0;\n var dindex = 0;\n var found = false;\n var entriesLength = entries.length;\n var entry;\n while (index < entriesLength) {\n entry = entries[index++];\n if (found || entry.key === key) {\n found = true;\n $delete(this, entry.key);\n } else dindex++;\n }\n while (dindex < entriesLength) {\n entry = entries[dindex++];\n if (!(entry.key === key && entry.value === value)) append(this, entry.key, entry.value);\n }\n }, { enumerable: true, unsafe: true });\n}\n","'use strict';\nvar defineBuiltIn = require('../internals/define-built-in');\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar toString = require('../internals/to-string');\nvar validateArgumentsLength = require('../internals/validate-arguments-length');\n\nvar $URLSearchParams = URLSearchParams;\nvar URLSearchParamsPrototype = $URLSearchParams.prototype;\nvar getAll = uncurryThis(URLSearchParamsPrototype.getAll);\nvar $has = uncurryThis(URLSearchParamsPrototype.has);\nvar params = new $URLSearchParams('a=1');\n\n// `undefined` case is a Chromium 117 bug\n// https://bugs.chromium.org/p/v8/issues/detail?id=14222\nif (params.has('a', 2) || !params.has('a', undefined)) {\n defineBuiltIn(URLSearchParamsPrototype, 'has', function has(name /* , value */) {\n var length = arguments.length;\n var $value = length < 2 ? undefined : arguments[1];\n if (length && $value === undefined) return $has(this, name);\n var values = getAll(this, name); // also validates `this`\n validateArgumentsLength(length, 1);\n var value = toString($value);\n var index = 0;\n while (index < values.length) {\n if (values[index++] === value) return true;\n } return false;\n }, { enumerable: true, unsafe: true });\n}\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar defineBuiltInAccessor = require('../internals/define-built-in-accessor');\n\nvar URLSearchParamsPrototype = URLSearchParams.prototype;\nvar forEach = uncurryThis(URLSearchParamsPrototype.forEach);\n\n// `URLSearchParams.prototype.size` getter\n// https://github.com/whatwg/url/pull/734\nif (DESCRIPTORS && !('size' in URLSearchParamsPrototype)) {\n defineBuiltInAccessor(URLSearchParamsPrototype, 'size', {\n get: function size() {\n var count = 0;\n forEach(this, function () { count++; });\n return count;\n },\n configurable: true,\n enumerable: true\n });\n}\n","import { analyticsCustomClickHandler } from '../../../../_shared-components/navigationMetrics';\n\nconst conditionalAnalytics = {\n searchHistory: {\n searchTermType: 'autosuggest-recentquery',\n linkName: 'searchbox-_-text-_-autosuggest',\n searchRecentQuerySource: 'product',\n },\n autosuggest: {\n searchTermType: 'autosuggest',\n linkName: 'searchbox-_-text-_-autosuggest',\n },\n natural: {\n searchTermType: 'natural',\n linkName: 'searchbox-_-text-_-searchbutton',\n },\n};\n\n/**\n * Determines the search type based on the aria-activedescendant value.\n *\n * @param {string} [ariaAD] - The aria-activedescendant value\n * from the search field.\n * @returns {'searchHistory' | 'autosuggest' | 'natural'} - the type of\n * search sumbission, listbox selection or text entry (natural)\n */\nconst getSearchType = (ariaAD) => {\n if (ariaAD) {\n if (ariaAD.startsWith('search-history')) return 'searchHistory';\n if (ariaAD.startsWith('autosuggest')) return 'autosuggest';\n }\n return 'natural';\n};\n\n/**\n * Extracts the index number from an aria-activedescendant value.\n *\n * @param {string} [ariaAD=''] - The aria-activedescendant attribute value.\n * @returns {string | null} - The extracted index if found, otherwise null.\n */\nconst getTermIndex = (ariaAD = '') => {\n const match = ariaAD.match(/-([^-]*)$/);\n const lastString = match?.[1];\n const isNumber = lastString && !Number.isNaN(Number(lastString));\n return isNumber ? lastString : null;\n};\n\n/**\n * Retrieves the appropriate analytics object for a given search type.\n *\n * @param {string} ariaAD - The aria-activedescendant value.\n * @param {'searchHistory' | 'autosuggest' | 'natural'} searchType\n * The detected search type (see getSearchType)\n * @param {object} [condAnalytics=conditionalAnalytics] - additional analytics\n * object, specific to the search type (see conditionalAnalytics above)\n * @returns {object} - The resolved analytics object, with position added.\n */\nconst getConditionalAnalytics = (\n ariaAD,\n searchType,\n condAnalytics = conditionalAnalytics\n) => {\n const analytics = condAnalytics[searchType];\n if (searchType !== 'natural' && analytics) {\n // this is the position indicator regardless of which listbox\n analytics.autoSuggestPosition = getTermIndex(ariaAD);\n }\n return analytics || {};\n};\n\n/**\n * The finalized analtyics object\n *\n * @param {string} ariaAD - The aria-activedescendant value.\n * @param {string} searchTerm - The submitted search term.\n * @returns {object} - The complete analytics data for submission.\n */\nconst getSumbitAnalytics = (ariaAD, searchTerm) => {\n if (!searchTerm) return null;\n const searchType = getSearchType(ariaAD);\n\n return {\n events: 'event1',\n searchTermClicked: searchTerm,\n ...getConditionalAnalytics(ariaAD, searchType),\n };\n};\n\n/**\n * gets finalized analytics and submits them\n * also includes convenience logging for env without metrics available\n *\n * @param {string} ariaAD - The aria-activedescendant value.\n * @param {string} searchTerm - The submitted search term.\n */\nconst handleSearchFormSubmissionAnalytics = (ariaAD, searchTerm) => {\n const config = getSumbitAnalytics(ariaAD, searchTerm);\n if (!config) return;\n\n // help with reviewing analytics locally or on try server\n if (document?.location?.hostname !== 'www.rei.com') {\n /* eslint-disable no-console */\n console.group('Metrics link config - searchMetrics');\n Object.entries(config).forEach(([key, value]) => {\n console.log(`${key}: ${value}`);\n });\n console.groupEnd();\n /* eslint-enable no-console */\n }\n\n analyticsCustomClickHandler(config);\n};\n\nexport {\n getSearchType,\n getTermIndex,\n getConditionalAnalytics,\n getSumbitAnalytics,\n handleSearchFormSubmissionAnalytics,\n};\n","/**\n * Search Form, input field, clear button, and search button\n *\n * Separation of concerns is very important here, as the JS and templates\n * here have to work alongside external components (namely, autosuggest,\n * and eventually search history).\n *\n * Code here should only apply to the elements above(e.g. the basic search\n * form). Nothing that applies to a supplemental search form package should\n * be included here (for example: adjusting Search History state)\n *\n * This file is also the sole source of handling analytics events on\n * form submission. Outside components should send a 'termSelected' custom\n * event rather than calling submit() directly on the search form.\n */\nimport { getDomElems } from '../../../../_shared-components/getDomElems';\nimport { handleSearchFormSubmissionAnalytics } from './searchMetrics';\n\n/**\n * Retrieves a search query parameter from the current URL.\n *\n * @param {string} param - The name of the query parameter to retrieve.\n * @returns {string|null} The value of the query parameter, or null if not found.\n */\nconst getSearchParam = (param) => {\n const params = new URLSearchParams(window.location.search);\n return params.get(param);\n};\n\n/**\n * Displays the clear button and adjusts the search field's margin.\n *\n * @param {HTMLInputElement} searchField - The search input field element.\n * @param {HTMLElement} clearButton - The clear button element.\n */\nconst showClearButton = (searchField, clearButton) => {\n clearButton.removeAttribute('aria-hidden');\n clearButton.setAttribute('data-visible', 'visible');\n searchField.setAttribute('style', 'margin-right: -44px;');\n};\n\n/**\n * Hides the clear button and resets the search field's margin.\n *\n * @param {HTMLInputElement} searchField - The search input field element.\n * @param {HTMLElement} clearButton - The clear button element.\n */\nconst hideClearButton = (searchField, clearButton) => {\n clearButton.setAttribute('aria-hidden', 'true');\n clearButton.setAttribute('data-visible', 'hidden');\n searchField.setAttribute('style', 'margin-right: 0;');\n};\n\n/**\n * Toggles the visibility of the clear button based on the search field's value.\n *\n * @param {HTMLInputElement} searchField - The search input field element.\n * @param {HTMLElement} clearButton - The clear button element.\n */\nconst setClearButtonVisibility = (searchField, clearButton) => {\n if (!searchField.value) {\n hideClearButton(searchField, clearButton);\n } else {\n showClearButton(searchField, clearButton);\n }\n};\n\n/**\n * Enables or disables the search button based on the search field's value.\n *\n * @param {HTMLInputElement} searchField - The search input field element.\n * @param {HTMLButtonElement} searchButton - The search button element.\n */\nconst enableSearchButton = (searchField, searchButton) => {\n if (searchField.value.trim().length === 0) {\n searchButton.classList.add('search__search-button--disabled');\n searchButton.setAttribute('aria-disabled', 'true');\n searchButton.setAttribute('disabled', 'disabled');\n } else if (searchField.value.trim().length > 0) {\n searchButton.classList.remove('search__search-button--disabled');\n searchButton.setAttribute('aria-disabled', 'false');\n searchButton.removeAttribute('disabled');\n }\n};\n\n/**\n * Clears the search field's value and refocuses it.\n *\n * @param {HTMLInputElement} searchField - The search input field element.\n */\nconst clearSearchField = (searchField) => {\n const inputElem = searchField;\n inputElem.value = '';\n searchField.focus();\n};\n\n// used to ensure analytics don't send twice\nlet analyticsLogged = false;\n\n/**\n * handle sending analytics\n * triggered on either natural search (term in box, enter/searchbutton)\n * Or when \"termSelected\" event is dispatched by autosuggest or recents\n *\n * @param {HTMLInputElement} searchField - The search input field element.\n */\nconst handleAnalytics = (searchField) => {\n if (analyticsLogged) return;\n const searchTerm = searchField.value;\n const ariaActivedescendant = searchField.getAttribute('aria-activedescendant');\n handleSearchFormSubmissionAnalytics(ariaActivedescendant, searchTerm);\n analyticsLogged = true;\n};\n\n/**\n * Handles the \"termSelected\" event, triggering analytics tracking,\n * and submitting the search form.\n *\n * @param {HTMLInputElement} searchField - The search input field element.\n * @param {HTMLFormElement} searchForm - The search form element.\n * @param {Event} e\n */\nconst handleTermSelected = (searchField, searchForm, e) => {\n e.preventDefault();\n handleAnalytics(searchField);\n searchForm.submit();\n};\n\n/**\n * Initializes the search form event listeners and sets up analytics tracking.\n *\n * @param {Object} selectors - The object containing CSS selectors for various form elements.\n * @param {string} selectors.searchForm - Selector for the search form element.\n * @param {string} selectors.searchField - Selector for the search input field.\n * @param {string} selectors.clearButton - Selector for the search clear button.\n * @param {string} selectors.searchButton - Selector for the search submit button.\n */\nconst init = (selectors) => {\n // check that all needed elements are available\n const searchElems = getDomElems(selectors);\n if (searchElems === null) return;\n\n analyticsLogged = false;\n\n const {\n searchForm,\n searchField,\n clearButton,\n searchButton,\n } = searchElems;\n\n // if we're on a search page with a query, populate the search field with it\n searchField.value = getSearchParam('q');\n // set initial clear button visibility based on above\n setClearButtonVisibility(searchField, clearButton);\n // enable or disable search button based on above\n enableSearchButton(searchField, searchButton);\n\n // Clear button event listeners\n clearButton.addEventListener('click', () => {\n clearSearchField(searchField);\n setClearButtonVisibility(searchField, clearButton);\n enableSearchButton(searchField, searchButton);\n });\n searchField.addEventListener('keyup', () => {\n setClearButtonVisibility(searchField, clearButton);\n });\n\n // search button event listener\n searchField.addEventListener('input', () => {\n enableSearchButton(searchField, searchButton);\n });\n\n // term submission/analytics event listeners\n document.addEventListener('termSelected', (e) => {\n handleTermSelected(searchField, searchForm, e);\n });\n searchForm.addEventListener('submit', (e) => {\n handleAnalytics(searchField, searchForm, e);\n });\n};\n\nexport default init;\n","const sliceSize = 10;\n\nexport const cleanSearchResult = (item) => item.replace(/\\s?-?'?/gi, '');\n\nexport const getStartsWithData = (data, cleanedSearchTerm) => data\n .filter((item) => cleanSearchResult(item).startsWith(cleanedSearchTerm));\n\nexport const getIncludesData = (data, cleanedSearchTerm) => data\n .filter((item) => !cleanSearchResult(item).startsWith(cleanedSearchTerm)\n && cleanSearchResult(item).includes(cleanedSearchTerm));\n\nexport const partitionData = (data, cleanSearchTerm) => data.map((term) => {\n // Build a regular expression pattern with optional special characters\n // in-between each letter of the search term\n let optionalSpecialCharacterPattern = '';\n for (let i = 0, len = cleanSearchTerm.length; i < len; i += 1) {\n optionalSpecialCharacterPattern += `${cleanSearchTerm[i]}\\\\W*`;\n }\n\n // Create the regular expression, ignoring case and matching only the first occurrence\n const optionalSpecialCharacterRegExp = new RegExp(optionalSpecialCharacterPattern, 'i');\n\n // Match the search term with optional special characters to the item in the term list\n const matches = term.match(optionalSpecialCharacterRegExp);\n\n // Define the parameters that allow search term highlighting in the term\n // list, note there should only ever be one occurrence\n const displayTerm = matches ? matches[0] : cleanSearchTerm;\n\n return {\n searchTerm: displayTerm,\n resultTitle: term,\n };\n});\n\nexport const cleanSearchTerm = (term) => {\n // Regular expression to match all non-word (special) characters\n const specialCharacterRegExp = term.length > 1 ? /\\W/g : '';\n\n return term.toLowerCase().replace(/[^a-z\\d]/gi, '').replace(specialCharacterRegExp, '');\n};\n\nexport const cleanFetchedItems = (fetchedItems) => [...fetchedItems]\n .map((item) => item.term.toLowerCase());\n\n/** @param {function} filterResults takes @param {array} fetchedItems and filters it by using\n * the current value from the input box, as well as multiple steps of regex that return\n * matched string characters to allow for dynamic styling\n */\nexport default (value = '', state = {}) => {\n const newState = state;\n /** @param {function} filterResults takes @param {array} fetchedItems and filters it by using\n * the current value from the input box, as well as multiple steps of regex that return\n * matched string characters to allow for dynamic styling\n */\n const cleanedSearchTerm = cleanSearchTerm(value);\n\n if (!newState.fetchedItems.length) return [];\n // Grab all the values from fetchedItems and map over them to produce a\n // new array that has them lowercased and with only their term\n let data = cleanFetchedItems(newState.fetchedItems);\n\n // Grabs data that starts with search term\n const startsWithData = getStartsWithData(data, cleanedSearchTerm);\n\n // Grabs data that contains, but doesn't start with search term\n const includesData = getIncludesData(data, cleanedSearchTerm);\n\n // Combines data sets, if needed\n data = (startsWithData.length < sliceSize) ? startsWithData.concat(includesData) : startsWithData;\n\n // partition search results into the entered chars and remaining chars\n data = partitionData(data, cleanedSearchTerm);\n\n newState.filteredResults = data.slice(0, sliceSize);\n return newState.filteredResults;\n};\n","const SEARCH_HISTORY = {\n LI_ID: (index) => `search-history-entry-${index}`,\n UL_ID: 'gnav-recent-search-list',\n LOCAL_STORAGE_KEY: 'savedSearches',\n SELECTOR: '[data-js=recent-search-box]',\n RECENTLY_SELECTED: 'recentSearchTermSelected',\n DELETE: {\n ID: 'search-history-delete',\n CSS: 'search-history__button',\n TEXT: 'Clear History',\n },\n TITLE: {\n CSS: 'search-history__title',\n TEXT: 'Search History',\n },\n};\n\nconst AUTOSUGGEST = {\n LI_ID: (index) => `autosuggest-result-${index}`,\n UL_ID: 'gnav-suggestion-list',\n SELECTOR: '[data-js=suggestion-box]',\n URL: {\n FALLBACK: 'https://www.rei.com/autosuggest/online/details',\n },\n};\n\nconst LISTBOX = {\n CSS: {\n VISUAL_FOCUS: 'searchbox-term',\n LIST_ITEM: 'searchbox-result',\n },\n ARIA_LIVE: {\n DIRECTIONS: 'Keyboard users, use up and down arrows to review and enter to select. Touch device users, explore by touch or with swipe gestures.',\n SELECTOR: '[data-js=\"feedback-holder\"]',\n },\n ALL_LI: {\n SELECTOR: `[id^=${AUTOSUGGEST.LI_ID('')}], [id^=${SEARCH_HISTORY.LI_ID('')}]`,\n },\n URL: {\n DOMAIN: 'https://www.rei.com/',\n },\n};\n\nexport {\n AUTOSUGGEST,\n SEARCH_HISTORY,\n};\nexport default LISTBOX;\n","/**\n * Listbox Utils | Search History & Autosuggest\n * Search History and Autosuggest are very similar in functionality, but must be able to work\n * independently of one another. This module is for methods that are used in both recents and\n * autosuggest listboxes.\n * @see [Definition of listbox]{@link https://www.w3.org/TR/wai-aria-practices/#Listbox}.\n * Used in reference to [combo box]{@link https://www.w3.org/TR/wai-aria-practices/#combobox}\n */\nimport { code, getKeyCode, keyCode } from '../../../../_shared-components/keyCode';\nimport LISTBOX from './constants';\n\n/**\n * Keys whose default action should be ignored on a keydown event.\n * @param {KeyboardEvent} e\n */\nconst preventDefaultOnKeyDown = (e) => {\n const keyCodeVal = getKeyCode(e);\n switch (keyCodeVal) {\n case code.ARROW_DOWN:\n case keyCode.ARROW_DOWN:\n case code.ARROW_UP:\n case keyCode.ARROW_UP:\n case code.END:\n case keyCode.END:\n e.preventDefault();\n break;\n default:\n break;\n }\n};\n\nconst getUpdatedIndexOnArrowDown = (currentIndex, length) => (\n (currentIndex < length - 1 && currentIndex > -1) ? currentIndex + 1 : 0\n);\n\nconst getUpdatedIndexOnArrowUp = (currentIndex, length) => (\n (currentIndex <= length && currentIndex > 0) ? currentIndex - 1 : length - 1\n);\n\n/**\n * Sets the input field with the value.\n * @param {HTMLInputElement} searchField\n * @param {string} value\n */\nconst setSearchField = (searchField, value = '') => {\n const search = searchField;\n search.value = value;\n};\n\n/**\n * Iterates through list entries and removes css indicating visual focus.\n * @param {HTMLLIElement[]} listEntries\n */\nconst cleanListEntries = (listEntries) => {\n [...listEntries].forEach((elem) => {\n elem.classList.remove(LISTBOX.CSS.VISUAL_FOCUS);\n elem.removeAttribute('aria-selected');\n });\n};\n\nconst resetListbox = (searchField, listEntries) => {\n searchField.setAttribute('aria-activedescendant', '');\n cleanListEntries(listEntries);\n};\n\n/**\n * Index for the list item element is the last substring of the id when split on '-'.\n * @param {HTMLLIElement} elem\n * @returns {number|number}\n */\nconst getIndexFromElement = (elem) => {\n const { id = null } = elem || {};\n const wordsArr = !id ? [] : id.split('-');\n return wordsArr.length < 1 ? -1 : (wordsArr[wordsArr.length - 1] * 1);\n};\n\n/**\n * Adds visual focus to a single listItem and updates aria-live region with descriptive context.\n * @param {HTMLInputElement} searchField\n * @param {HTMLLIElement} listItem - entry to add visual focus to\n * @param {HTMLLIElement[]} listEntries - button element only for clear history\n */\nconst setVisualFocus = (searchField, listItem, listEntries) => {\n cleanListEntries(listEntries);\n searchField.setAttribute('aria-activedescendant', listItem.id);\n listItem.setAttribute('aria-selected', 'true');\n listItem.classList.add(LISTBOX.CSS.VISUAL_FOCUS);\n};\n\n/**\n * @param {HTMLDivElement} listboxElem - which contains the data-visible attribute which may\n * need to be updated\n * @param {boolean} newValue - most recent result of logic determining if listbox should visible\n * (true) or hidden (false)\n * @returns {boolean} - true if a difference exists between the previous and newValue\n */\nconst shouldUpdateVisibility = (listboxElem, newValue) => {\n const { dataset: { visible: visibleValue } } = listboxElem;\n const oldValue = visibleValue === 'visible';\n return oldValue !== newValue;\n};\n\nconst addMouseMoveEventListeners = (dynamicElem, enterCallback, leaveCallback) => {\n dynamicElem.addEventListener('mouseenter', enterCallback);\n dynamicElem.addEventListener('mouseleave', leaveCallback);\n};\n\n/**\n * A custom event for when a search term is selected.\n * Used to indicate to search.js to handle the search input submit event\n * and send analytics. This keeps the submission/analytics concern\n * housed ONLY in search.js\n *\n * @constant {CustomEvent} termSelectedEvent\n * @event termSelected\n */\nconst termSelectedEvent = new CustomEvent(\n 'termSelected',\n {\n bubbles: true,\n cancelable: true,\n },\n);\n\n/**\n * Retrieves the `id` and `textContent` of a list item (`
  • `).\n * Used for updating the search field when an autosuggest or\n * search history term is selected\n *\n * @param {HTMLElement} li - The
  • element to extract data from.\n * @returns {{ id: string, selectedText: string } | null}\n * An object containing the `id` and trimmed `selectedText`,\n * or null if li is not an
  • .\n */\nconst getTextAndIdFromListEl = (li) => {\n if (li instanceof HTMLLIElement) {\n return {\n id: li.id,\n selectedText: li.textContent.trim(),\n };\n }\n return null;\n};\n\n/**\n * Retrieves the currently selected
  • element using the\n * aria-activedescendant attribute.\n *\n * @param {HTMLInputElement} searchField - The search input field.\n * @param {HTMLElement} listbox - The listbox element containing the options.\n * (search history or autosuggest)\n * @returns {HTMLLIElement | null} - The selected
  • element, or null\n */\nconst getSelectedElementByAria = (searchField, listbox) => {\n const id = searchField?.getAttribute('aria-activedescendant');\n const li = id ? listbox?.querySelector(`#${id}`) : null;\n return li && li instanceof HTMLLIElement ? li : null;\n};\n\n/**\n * Determines the type of listbox (search history or autosuggest)\n * based on the aria-activedescendant value.\n *\n * @param {HTMLInputElement} searchField - The search input field.\n * @returns {'search-history' | 'autosuggest' | null} - The type of listbox,\n * or `null` if unknown.\n */\nconst getListboxType = (searchField) => {\n const id = searchField?.getAttribute('aria-activedescendant');\n if (id?.startsWith('search-history')) return 'search-history';\n if (id?.startsWith('autosuggest')) return 'autosuggest';\n return null;\n};\n\n/**\n * Updates the aria-activedescendant attribute and sets the search field value.\n *\n * @param {HTMLInputElement} searchField - The search input field.\n * @param {string} selectedText - The text to set in the search field.\n * @param {string} [id=''] - The ID of the selected listbox item.\n */\nconst updateAriaAndSearchTerm = (\n searchField,\n selectedText,\n id = '',\n) => {\n setSearchField(searchField, selectedText);\n searchField.setAttribute('aria-activedescendant', id);\n};\n\n/**\n * Updates the aria-activedescendant attribute and sets the search field value.\n * and dispatches a `termSelected` event when a search term is chosen\n *\n * @param {HTMLInputElement} searchField - The search input field.\n * @param {string} selectedText - The selected search term.\n * @param {string} [id=''] - The ID of the selected item.\n */\nconst dispatchTermSelectedEvent = (\n searchField,\n selectedText,\n id = '',\n) => {\n if (selectedText) {\n updateAriaAndSearchTerm(searchField, selectedText, id);\n document.dispatchEvent(termSelectedEvent);\n }\n};\n\nexport {\n addMouseMoveEventListeners,\n getUpdatedIndexOnArrowDown,\n getUpdatedIndexOnArrowUp,\n getIndexFromElement,\n preventDefaultOnKeyDown,\n resetListbox,\n shouldUpdateVisibility,\n setSearchField,\n setVisualFocus,\n termSelectedEvent,\n getTextAndIdFromListEl,\n getSelectedElementByAria,\n getListboxType,\n updateAriaAndSearchTerm,\n dispatchTermSelectedEvent,\n};\n","/**\n * Autosuggest\n * Contains main functionality for the search autosuggest.\n */\nimport { getDomElems } from '../../../../_shared-components/getDomElems';\nimport filterResults from './filterResults';\nimport getScriptData from '../../util/getScriptData';\nimport { getKeyCode, code } from '../../../../_shared-components/keyCode';\nimport LISTBOX, { AUTOSUGGEST } from './constants';\nimport * as listbox from './listboxUtil';\n\n/**\n * State holds the values for autosuggest and includes\n * @param {array} fetchedItems which is the result of the fetch call,\n * @param {array} filteredResults is an array of ten results,\n*/\nconst state = {\n fetchedItems: [],\n filteredResults: [],\n};\n\n/**\n * Determines whether the autosuggest listbox is open.\n *\n * - Checks if the `suggestionBox` element exists in the state.\n * - Retrieves its `data-visible` attribute.\n * - Returns true if the value is 'visible', otherwise false.\n *\n * @returns {boolean} - true if the autosuggest listbox is open.\n */\nconst autosuggestListboxIsOpen = () => {\n const { suggestionBox } = state;\n const { dataset: { visible } } = suggestionBox;\n return visible === 'visible';\n};\n\n/**\n * Grabs Autosuggest data JSON from #gnav-data blob. If not found uses absolute url fallback value\n * @returns {string} url\n */\nconst getAutosuggestTarget = () => {\n const {\n autosuggestTarget: targetUrl = null,\n } = getScriptData('gnav-data') || {};\n return targetUrl === null ? AUTOSUGGEST.URL.FALLBACK : targetUrl;\n};\n\n/**\n * Pings an endpoint and assigns the results to state's fetchedItems property. If an error occurs,\n * it is logged to the dev console and fetchedItems is set to an empty array.\n * @param {string} fetchPoint: url to ping\n */\nexport const fetchData = (fetchPoint) => {\n fetch(fetchPoint)\n .then((response) => {\n const { ok, status, url } = response || {};\n if (!ok) {\n // eslint-disable-next-line no-console\n console.error(`url: ${url} is responding with status code: ${status}`);\n }\n return ok ? response.json() : [];\n })\n .then((response) => {\n state.fetchedItems = response;\n })\n // eslint-disable-next-line no-console\n .catch((e) => console.error(e));\n};\n\n/**\n * If resultTitle exists then returns string containing bolded substring via markup.\n * Otherwise returns unchanged searchTerm string.\n * @param {string} searchTerm\n * @param {string} resultTitle\n * @returns {*}\n */\nconst getInnerHtml = (searchTerm, resultTitle) => (\n resultTitle.replace(searchTerm, `${searchTerm}`)\n);\n\n/**\n * @param {number} resultCount - current number of available autosuggest options\n * @param {string} searchTerm - the characters contained within the search input\n * @returns {string} - description of available autosuggest options for a searchTerm,\n * including directions on how to navigation the open listbox.\n */\nconst getAriaLiveTextForResults = (resultCount, searchTerm) => (\n (resultCount === 1) ? `There is 1 result available that contains \"${searchTerm}\". ${LISTBOX.ARIA_LIVE.DIRECTIONS}`\n : `There are ${resultCount} results available that contain \"${searchTerm}\".${resultCount > 0 ? ` ${LISTBOX.ARIA_LIVE.DIRECTIONS}` : ''}`\n);\n\n/**\n * Will remove visual focus for autosuggest list item when mouse leaves element.\n * Updates aria-live text to total result count\n * @param e\n */\nconst onMouseLeave = (e) => {\n const { target } = e;\n const { suggestionBox, ariaLiveRegion, searchField } = state;\n const listEntries = suggestionBox.querySelectorAll(LISTBOX.ALL_LI.SELECTOR);\n /* only remove visual focus if target has it, otherwise do nothing */\n if (target.classList.contains(LISTBOX.CSS.VISUAL_FOCUS)) {\n listbox.resetListbox(searchField, listEntries);\n ariaLiveRegion.textContent = getAriaLiveTextForResults(\n listEntries.length,\n searchField.value.trim()\n );\n }\n};\n\n/**\n * Add visual focus to autosuggest list item.\n * @param e\n */\nconst onMouseEnter = (e) => {\n const { target } = e;\n const { suggestionBox, ariaLiveRegion, searchField } = state;\n const listEntries = suggestionBox.querySelectorAll(LISTBOX.ALL_LI.SELECTOR);\n listbox.setVisualFocus(searchField, target, listEntries);\n ariaLiveRegion.textContent = '';\n};\n\n/**\n * Creates and appends markup to the DOM containing the list of autosuggest options with the\n * relevant characters bolded.\n * @param {object[]} results Array of (at most 10) options\n *\n * About data-cnstrc-item-section and data-cnstrc-item-name attributes:\n * https://docs.constructor.com/docs/integrating-with-constructor-behavioral-tracking-data-driven-event-tracking#result-item\n * https://docs.constructor.com/docs/faq-api-what-is-a-section-as-referenced-in-the-api\n */\nexport const appendResults = (results) => {\n const { suggestionList } = state;\n /* remove contents from ul element */\n const ul = suggestionList;\n ul.innerHTML = '';\n /* add list items to ul */\n [...results].forEach(({ searchTerm, resultTitle }, index) => {\n const li = document.createElement('li');\n li.className = LISTBOX.CSS.LIST_ITEM;\n /* id with index used for tracking focus & building metrics */\n li.id = AUTOSUGGEST.LI_ID(index);\n li.innerHTML = getInnerHtml(searchTerm, resultTitle);\n li.setAttribute('role', 'option');\n li.setAttribute('aria-label', resultTitle);\n /* Add Constructor search beacon tracking attributes */\n li.setAttribute('data-cnstrc-item-section', 'Search Suggestions');\n li.setAttribute('data-cnstrc-item-name', resultTitle);\n listbox.addMouseMoveEventListeners(li, onMouseEnter, onMouseLeave);\n ul.appendChild(li);\n });\n};\n\n/**\n * Controls visibility / expand-collapse of autosuggestion listbox\n * @param {HTMLDivElement} suggestionBox - element that contains the list entries of recent\n * searches or filtered results\n * @param {HTMLInputElement} searchField - input element of search field\n * @param {boolean} isVisible - boolean used to determine state of visibility / expansion\n */\nexport const setSuggestionBoxVisibility = (suggestionBox, searchField, isVisible = false) => {\n if (!isVisible) {\n listbox.resetListbox(searchField, [...suggestionBox.querySelectorAll(LISTBOX.ALL_LI.SELECTOR)]);\n }\n searchField.parentElement.setAttribute('aria-expanded', `${isVisible}`);\n suggestionBox.setAttribute('data-visible', isVisible ? 'visible' : 'hidden');\n};\n\nconst onFocus = (suggestionBox, e) => {\n const { target: searchField } = e;\n const searchTerm = searchField.value.trim();\n if (searchTerm.length > 0) {\n /* update state */\n state.filteredResults = filterResults(searchTerm, state);\n const { ariaLiveRegion, filteredResults } = state;\n appendResults(filteredResults);\n const isVisible = (filteredResults && filteredResults.length > 0);\n if (listbox.shouldUpdateVisibility(suggestionBox, isVisible)) {\n setSuggestionBoxVisibility(suggestionBox, searchField, isVisible);\n }\n ariaLiveRegion.textContent = getAriaLiveTextForResults(filteredResults.length, searchTerm);\n }\n};\n\nconst onBlur = (suggestionBox, e) => {\n const { ariaLiveRegion } = state;\n const { target: searchField } = e;\n setSuggestionBoxVisibility(suggestionBox, searchField);\n ariaLiveRegion.textContent = '';\n};\n\n/**\n * Handles mouse down events on the autosuggest listbox.\n *\n * - Retrieves the currently selected
  • element.\n * - If no item is selected, the function exits.\n * - If the selected item has valid text, it dispatches a termSelected event.\n *\n * @param {HTMLInputElement} searchField - The search input field.\n * @param {HTMLElement} suggestionList - The autosuggest listbox.\n */\nconst onMouseDown = (searchField, suggestionList) => {\n const li = listbox.getSelectedElementByAria(searchField, suggestionList);\n if (!li) return;\n const { id, selectedText } = listbox.getTextAndIdFromListEl(li);\n if (!selectedText) return;\n listbox.dispatchTermSelectedEvent(searchField, selectedText, id);\n};\n\n/**\n * Handles the keyboard logic for list entries in SuggestionBox\n * @param e\n */\nexport const onKeyUp = (e) => {\n const {\n ariaLiveRegion,\n suggestionBox,\n searchField,\n } = state;\n // const { dataset: { visible } } = suggestionBox;\n if (!autosuggestListboxIsOpen()) return;\n const listEntries = suggestionBox.querySelectorAll(`.${LISTBOX.CSS.LIST_ITEM}`);\n const currentIndex = listbox.getIndexFromElement(suggestionBox.querySelector(`.${LISTBOX.CSS.VISUAL_FOCUS}`));\n const keyCodeVal = getKeyCode(e);\n const searchTerm = searchField.value.trim();\n switch (keyCodeVal) {\n case code.ARROW_DOWN: {\n const updatedIndex = listbox.getUpdatedIndexOnArrowDown(currentIndex, listEntries.length);\n listbox.setVisualFocus(searchField, listEntries[updatedIndex], listEntries);\n ariaLiveRegion.textContent = '';\n }\n break;\n case code.ARROW_UP: {\n const updatedIndex = listbox.getUpdatedIndexOnArrowUp(currentIndex, listEntries.length);\n listbox.setVisualFocus(searchField, listEntries[updatedIndex], listEntries);\n ariaLiveRegion.textContent = '';\n }\n break;\n case code.ESCAPE:\n listbox.setSearchField(searchField);\n searchField.focus();\n setSuggestionBoxVisibility(suggestionBox, searchField);\n ariaLiveRegion.textContent = '';\n\n break;\n case code.END:\n searchField.focus();\n /* places cursor at the end text in field (if any) */\n searchField.setSelectionRange(searchField.value.length, searchField.value.length);\n listbox.resetListbox(searchField, listEntries);\n ariaLiveRegion.textContent = getAriaLiveTextForResults(listEntries.length, searchTerm);\n\n break;\n case code.HOME:\n searchField.focus();\n listbox.resetListbox(searchField, listEntries);\n ariaLiveRegion.textContent = getAriaLiveTextForResults(listEntries.length, searchTerm);\n\n break;\n case code.ARROW_LEFT:\n case code.ARROW_RIGHT:\n listbox.resetListbox(searchField, listEntries);\n ariaLiveRegion.textContent = getAriaLiveTextForResults(listEntries.length, searchTerm);\n break;\n default:\n if (searchTerm.length > 0) {\n ariaLiveRegion.textContent = getAriaLiveTextForResults(listEntries.length, searchTerm);\n }\n break;\n }\n};\n\n/**\n * Handles keydown events for the autosuggest listbox.\n *\n * - Exits immediately if the autosuggest listbox is not open.\n * - If the key pressed is not \"Enter\", calls the listbox\n * preventDefaultOnKeyDown and exits.\n * - Retrieves the currently selected list item:\n * - If no item is selected, the function exits.\n * - If the selected item has no valid text, the function exits.\n * - Otherwise, it dispatches a termSelected event.\n *\n * @param {HTMLInputElement} searchField - The search input field.\n * @param {HTMLElement} suggestionList - The autosuggest listbox.\n * @param {KeyboardEvent} e - The keydown event object.\n */\nconst onKeyDown = (searchField, suggestionList, e) => {\n if (!autosuggestListboxIsOpen()) return;\n const keyCodeVal = getKeyCode(e);\n\n // handler for navigation key events\n // see listbox - this only applies to certain keys\n if (keyCodeVal !== code.ENTER && keyCodeVal !== code.NUMPAD_ENTER) {\n listbox.preventDefaultOnKeyDown(e);\n return;\n }\n\n // handler for potential selection of search terms\n // we can use aria to determine if this is a listbox selection\n const li = listbox.getSelectedElementByAria(searchField, suggestionList);\n if (!li) return;\n\n const { id, selectedText } = listbox.getTextAndIdFromListEl(li);\n if (!selectedText) return;\n\n e.preventDefault();\n listbox.dispatchTermSelectedEvent(searchField, selectedText, id);\n};\n\n/**\n * Updates filteredResults, DOM, and/or toggles visibility as needed before invoking\n * onKeyUp method.\n * @param {HTMLDivElement} suggestionBox\n * @param {HTMLInputElement} searchField\n * @param {KeyboardEvent} e\n */\nconst onInput = (suggestionBox, searchField, e) => {\n const searchTerm = searchField.value.trim();\n /* only update DOM when necessary */\n state.filteredResults = filterResults(searchTerm, state);\n appendResults(state.filteredResults);\n\n const isVisible = (searchTerm !== ''\n && (state.filteredResults && state.filteredResults.length > 0));\n if (listbox.shouldUpdateVisibility(suggestionBox, isVisible)) {\n setSuggestionBoxVisibility(suggestionBox, searchField, isVisible);\n }\n\n // needed to update aria live region\n onKeyUp(e);\n};\n\n/* init */\nconst init = (selectors) => {\n const searchElems = getDomElems(selectors);\n if (searchElems === null) return;\n /* build state */\n const {\n searchField,\n suggestionBox,\n suggestionList,\n searchForm,\n } = searchElems;\n const ariaLiveRegion = searchForm.parentElement.querySelector(LISTBOX.ARIA_LIVE.SELECTOR);\n searchField.setAttribute('aria-activedescendant', '');\n Object.assign(state, searchElems, { ariaLiveRegion });\n /* Add Event Listeners */\n searchField.addEventListener('focus', onFocus.bind(null, suggestionBox));\n searchField.addEventListener('blur', onBlur.bind(null, suggestionBox));\n searchField.addEventListener(\n 'keydown',\n onKeyDown.bind(null, searchField, suggestionList)\n );\n searchField.addEventListener('keyup', onKeyUp);\n searchField.addEventListener('input', onInput.bind(null, suggestionBox, searchField));\n suggestionList.addEventListener(\n 'mousedown',\n onMouseDown.bind(null, searchField, suggestionList)\n );\n fetchData(getAutosuggestTarget());\n};\n\nexport { state as suggestState };\nexport default init;\n","/**\n * Recent Searches | Search History\n * Contains main functionality for \"Recent Searches\" (aka user search history).\n * Is only visible when the input for search has focus, is empty (no text), and at least one\n * entry / previously saved search exists. The only exception is if the user presses \"escape\".\n * Only then the search field will be empty, with focus, and NOT display Recent Searches.\n *\n * NOT AVAILABLE to 3rd party sites as window.localStorage cannot cross domains (as coded).\n */\nimport { getDomElems } from '../../../../_shared-components/getDomElems';\nimport { code, getKeyCode, keyCode } from '../../../../_shared-components/keyCode';\nimport LISTBOX, { SEARCH_HISTORY } from './constants';\nimport * as listbox from './listboxUtil';\nimport getScriptData from '../../util/getScriptData';\n\nconst recentSearchState = {\n maxCapacity: 10,\n recentSearches: [],\n};\n/* Resets state on init */\nconst setStateOnInit = () => {\n recentSearchState.maxCapacity = 10;\n recentSearchState.recentSearches = [];\n recentSearchState.recentHistoryBox = {};\n};\n\n/**\n * Retrieves the recentSearches from localStorage stored under the key 'savedSearches'\n * @param {Window} win\n */\nconst getRecentSearches = (win = window) => (\n JSON.parse(win.localStorage.getItem(SEARCH_HISTORY.LOCAL_STORAGE_KEY)) || []\n);\n\n/**\n * Removes the savedSearches localStorage key and data\n * @param {Window} win - global window\n */\nconst clearSearchHistory = (win = window) => {\n win.localStorage.removeItem(SEARCH_HISTORY.LOCAL_STORAGE_KEY);\n};\n\n/**\n * Sets search history to local storage.\n * @param {object[]} searchHistory - array of objects with a single property: \"searchTerm\"\n * @param win\n */\nconst setRecentSearches = (searchHistory, win = window) => {\n win.localStorage.setItem(SEARCH_HISTORY.LOCAL_STORAGE_KEY, JSON.stringify(searchHistory));\n};\n\n/**\n * Calls getRecentSearches to see if there are any recentSearches, checks to see if the current\n * searchTerm is empty, removes a recentSearch if there is are more than ten and then sets the\n * current searchTerm\n * @param {string} searchTerm\n * @param {Window} win\n */\nconst addToSearchHistory = (searchField, win = window) => {\n const searchTerm = searchField?.value?.trim();\n const { maxCapacity } = recentSearchState;\n if (!searchTerm) return;\n\n const recentSearches = getRecentSearches(win)\n .filter((search) => search.searchTerm.toLowerCase() !== searchTerm.toLowerCase());\n\n if (recentSearches.length >= maxCapacity) {\n recentSearches.pop();\n }\n setRecentSearches([{ searchTerm }, ...recentSearches]);\n};\n\n/**\n * Checks if element is the clear search history button by id\n * @param {HTMLLIElement} elemToCheck\n * @returns {boolean} - true if element is the clear search history button\n */\nconst isDeleteSearchHistoryButton = (elemToCheck) => (\n elemToCheck && elemToCheck.firstElementChild\n && elemToCheck.firstElementChild.id === SEARCH_HISTORY.DELETE.ID\n);\n\n/**\n * @param {number} listEntryCount Current count clickable list items in recent searches.\n * Number will always be greater than one because the delete history button is included.\n * @returns {string} describing the current number of Recent Search History entries, including\n * directions on how to navigation the open listbox.\n */\nconst getAriaLiveTextForTotalResults = (listEntryCount) => (\n `Recent Search History has ${listEntryCount} options available. ${LISTBOX.ARIA_LIVE.DIRECTIONS}`\n);\n\nconst getAllListEntries = () => (\n recentSearchState.recentHistoryBox.querySelectorAll(LISTBOX.ALL_LI.SELECTOR)\n);\n\n/**\n * Creates List Entry with a child element whose tagName and properties are\n * specified in the params. Used to build the title and delete button list entries.\n * @param {string} childTagName: string tagName. Ex. 'button', 'div', 'span'.\n * @param {object} elemPropsToSet: properties to set for the child element\n * @returns {HTMLLIElement}\n */\nconst createListEntryWithChildElem = (childTagName, elemPropsToSet) => {\n const listEntry = document.createElement('li');\n listEntry.className = 'search-history__entry';\n const elem = document.createElement(childTagName);\n Object.keys(elemPropsToSet).forEach((key) => {\n elem[key] = elemPropsToSet[key];\n });\n listEntry.appendChild(elem);\n return listEntry;\n};\n\nconst onMouseLeave = (e) => {\n const { target } = e;\n const { ariaLiveRegion, searchField } = recentSearchState;\n const listEntries = getAllListEntries();\n if (target.classList.contains(LISTBOX.CSS.VISUAL_FOCUS)) {\n listbox.resetListbox(searchField, listEntries);\n ariaLiveRegion.textContent = getAriaLiveTextForTotalResults(listEntries.length);\n }\n};\n\nconst onMouseEnter = (e) => {\n const { target } = e;\n const { ariaLiveRegion, searchField } = recentSearchState;\n const listEntries = getAllListEntries();\n listbox.setVisualFocus(searchField, target, listEntries);\n ariaLiveRegion.textContent = '';\n};\n\n/**\n * Creates, adds mouseEventListeners, and appends markup to the DOM with the Search History list.\n * First entry is read-only title (unclickable, unfocusable). The last entry is a delete button\n * so user can clear their recent search history.\n * @param {HTMLDivElement} recentHistoryBox listbox and parent element of ul\n * @param {object[]} results: Array of previously saved searches\n */\nconst appendRecentSearches = (recentHistoryBox, results = []) => {\n const ul = recentHistoryBox.querySelector(`#${SEARCH_HISTORY.UL_ID}`);\n ul.innerHTML = '';\n /* First entry of recent searches results is title */\n ul.appendChild(createListEntryWithChildElem('div', {\n className: SEARCH_HISTORY.TITLE.CSS,\n textContent: SEARCH_HISTORY.TITLE.TEXT,\n }));\n\n [...results].forEach(({ searchTerm }, index) => {\n const li = document.createElement('li');\n li.className = LISTBOX.CSS.LIST_ITEM;\n li.textContent = searchTerm;\n li.setAttribute('aria-label', searchTerm);\n li.setAttribute('role', 'option');\n /* id with index used for building metrics.link config */\n li.setAttribute('id', `${SEARCH_HISTORY.LI_ID(index)}`);\n /* Add MouseEnter, MouseLeave listeners */\n listbox.addMouseMoveEventListeners(li, onMouseEnter, onMouseLeave);\n ul.appendChild(li);\n });\n /* Last entry of recent searches is clear search history button */\n const clearHistoryListItem = createListEntryWithChildElem('button', {\n className: SEARCH_HISTORY.DELETE.CSS,\n id: SEARCH_HISTORY.DELETE.ID,\n textContent: SEARCH_HISTORY.DELETE.TEXT,\n type: 'button',\n tabIndex: '-1',\n });\n clearHistoryListItem.setAttribute('role', 'option');\n clearHistoryListItem.setAttribute('id', `${SEARCH_HISTORY.LI_ID(results.length)}`);\n clearHistoryListItem.setAttribute('aria-label', `${SEARCH_HISTORY.DELETE.TEXT}, button`);\n /* add listener to button (not li) */\n listbox.addMouseMoveEventListeners(clearHistoryListItem, onMouseEnter, onMouseLeave);\n ul.appendChild(clearHistoryListItem);\n};\n\n/**\n * Controls visibility / expand-collapse of recentSearchBox for both recent searches and\n * filtered results (aka autocomplete).\n * @param {HTMLDivElement} recentHistoryBox - element that contains the list entries of recent\n * searches or filtered results\n * @param {HTMLInputElement} searchField - input element of search field\n * @param {boolean} isVisible - boolean used to determine state of visibility / expansion\n */\nconst setRecentSearchBoxVisibility = (recentHistoryBox, searchField, isVisible = false) => {\n const searchTerm = searchField.value.trim();\n if (!isVisible || searchTerm.length > 0) {\n listbox.resetListbox(searchField, [...getAllListEntries()]);\n recentHistoryBox.setAttribute('data-visible', 'hidden');\n }\n if (searchTerm.length === 0) {\n searchField.parentElement.setAttribute('aria-expanded', `${isVisible}`);\n recentHistoryBox.setAttribute('data-visible', isVisible ? 'visible' : 'hidden');\n }\n};\n\n/**\n * Resets search history state, visibility, and focus when user deletes all recent searches\n * @param {HTMLDivElement} recentHistoryBox\n * @param {HTMLInputElement} searchField\n */\nconst deleteAllRecentSearches = (recentHistoryBox, searchField) => {\n const { ariaLiveRegion } = recentSearchState;\n clearSearchHistory();\n recentSearchState.recentSearches = [];\n ariaLiveRegion.textContent = '';\n setRecentSearchBoxVisibility(recentHistoryBox, searchField);\n};\n\n/**\n * Determines whether the recent search listbox should be open.\n *\n * The listbox is considered open if:\n * - `recentSearches` exists and contains at least one search term.\n * - The search input field is empty (i.e., no user input).\n *\n * @returns {boolean} - true if the recent search listbox should be open\n */\nconst recentSearchListboxShouldShow = () => {\n const { recentSearches, searchField } = recentSearchState;\n const searchTerm = searchField.value.trim();\n return (\n recentSearches\n && recentSearches.length > 0\n && searchTerm.length === 0\n );\n};\n\n/**\n * Handles the keyboard logic for list entries in RecentSearchBox\n * @param e\n */\nconst handleKeyUp = (e) => {\n const {\n ariaLiveRegion,\n recentHistoryBox,\n searchField,\n } = recentSearchState;\n /* limit results to current list */\n const listEntries = recentHistoryBox.querySelectorAll(LISTBOX.ALL_LI.SELECTOR);\n const currentIndex = listbox.getIndexFromElement(recentHistoryBox.querySelector(`.${LISTBOX.CSS.VISUAL_FOCUS}`));\n const keyCodeVal = getKeyCode(e);\n\n switch (keyCodeVal) {\n case code.ARROW_DOWN:\n case keyCode.ARROW_DOWN: {\n const updatedIndex = listbox.getUpdatedIndexOnArrowDown(currentIndex, listEntries.length);\n ariaLiveRegion.textContent = '';\n listbox.setVisualFocus(searchField, listEntries[updatedIndex], listEntries);\n localStorage.setItem(\n SEARCH_HISTORY.RECENTLY_SELECTED,\n listEntries[updatedIndex]?.innerText.trim()\n );\n break;\n }\n case code.ARROW_UP:\n case keyCode.ARROW_UP: {\n const updatedIndex = listbox.getUpdatedIndexOnArrowUp(currentIndex, listEntries.length);\n listbox.setVisualFocus(searchField, listEntries[updatedIndex], listEntries);\n ariaLiveRegion.textContent = '';\n localStorage.setItem(\n SEARCH_HISTORY.RECENTLY_SELECTED,\n listEntries[updatedIndex]?.innerText.trim()\n );\n break;\n }\n case code.ESCAPE:\n case keyCode.ESCAPE:\n searchField.focus();\n /* close search history. Only case where searchField has focus and does\n * NOT display search history */\n setRecentSearchBoxVisibility(recentHistoryBox, searchField);\n ariaLiveRegion.textContent = '';\n break;\n case code.END:\n case keyCode.END:\n case code.HOME:\n case keyCode.HOME:\n searchField.focus();\n listbox.resetListbox(searchField, listEntries);\n ariaLiveRegion.textContent = getAriaLiveTextForTotalResults(listEntries.length);\n break;\n case code.ARROW_LEFT:\n case keyCode.ARROW_LEFT:\n case code.ARROW_RIGHT:\n case keyCode.ARROW_RIGHT:\n listbox.resetListbox(searchField, listEntries);\n ariaLiveRegion.textContent = getAriaLiveTextForTotalResults(listEntries.length);\n break;\n default:\n break;\n }\n};\n\nconst onKeyUp = (recentHistoryBox, e) => {\n const {\n recentSearches,\n ariaLiveRegion,\n searchForm,\n searchField,\n } = recentSearchState;\n // determine if search history listbox is open\n const isVisible = recentSearchListboxShouldShow();\n\n const visibilityChanged = listbox.shouldUpdateVisibility(recentHistoryBox, isVisible);\n if (visibilityChanged) {\n setRecentSearchBoxVisibility(recentHistoryBox, searchField, isVisible);\n /* If autosuggest is not enabled then set aria-expanded & clear aria-live */\n if (!isVisible && searchForm.querySelectorAll('[role=\"listbox\"]').length === 1) {\n searchField.parentElement.setAttribute('aria-expanded', 'false');\n ariaLiveRegion.textContent = '';\n }\n }\n if (isVisible) {\n /* update DOM only when necessary */\n if (visibilityChanged) {\n appendRecentSearches(recentHistoryBox, recentSearches);\n /* increment length to include delete history button */\n ariaLiveRegion.textContent = getAriaLiveTextForTotalResults(recentSearches.length + 1);\n }\n handleKeyUp(e);\n }\n};\n\n/**\n * Handles keydown events for the recent search history listbox.\n *\n * - If the search history listbox is not open, we exit\n * - If the key pressed is not \"Enter\" we pass to the preventDefault\n * funciton, and exit\n * - If an item is selected in the listbox:\n * - If it's a \"Clear History\" button, it clears recent searches.\n * - Otherwise, it dispatches a `termSelected` event.\n *\n * @param {HTMLInputElement} searchField - The search input field.\n * @param {HTMLElement} recentHistoryBox - The search history listbox.\n * @param {KeyboardEvent} e - The keydown event object.\n */\nconst onKeyDown = (searchField, recentHistoryBox, e) => {\n if (!recentSearchListboxShouldShow()) return;\n const keyCodeVal = getKeyCode(e);\n\n // handler for navigation key events\n // see listbox - this only applies to certain keys\n if (keyCodeVal !== code.ENTER && keyCodeVal !== code.NUMPAD_ENTER) {\n listbox.preventDefaultOnKeyDown(e);\n return;\n }\n\n // handler for potential selection of search terms\n // we can use aria to determine if this is a listbox selection\n const li = listbox.getSelectedElementByAria(searchField, recentHistoryBox);\n if (!li) return;\n\n e.preventDefault();\n if (isDeleteSearchHistoryButton(li)) {\n deleteAllRecentSearches(recentHistoryBox, searchField);\n } else {\n const { id, selectedText } = listbox.getTextAndIdFromListEl(li);\n if (!selectedText) return;\n listbox.dispatchTermSelectedEvent(searchField, selectedText, id);\n }\n};\n\nconst onFocus = (recentHistoryBox, e) => {\n const { target: searchField } = e;\n const searchTerm = searchField.value.trim();\n const { recentSearches = [], ariaLiveRegion } = recentSearchState;\n if (recentSearches && recentSearches.length > 0 && searchTerm.length === 0) {\n setRecentSearchBoxVisibility(recentHistoryBox, searchField, true);\n appendRecentSearches(recentHistoryBox, recentSearches);\n /* increment recentSearches length to include delete history button */\n ariaLiveRegion.textContent = getAriaLiveTextForTotalResults(recentSearches.length + 1);\n }\n};\n\nconst onBlur = (ariaLiveRegion, recentHistoryBox, e) => {\n const { target: searchField } = e;\n const ariaLive = ariaLiveRegion;\n setRecentSearchBoxVisibility(recentHistoryBox, searchField);\n ariaLive.textContent = '';\n};\n\n/**\n * Handles mouse down events on the recent search history listbox.\n *\n * - If no
  • is selected, we exit.\n * - If the selected item is a \"Clear History\" button, it:\n * - Registers a mouseup event listener to return focus to the search field.\n * - Calls deleteAllRecentSearches() to clear the history.\n * - Otherwise, it dispatches a termSelected event.\n *\n * @param {HTMLInputElement} searchField - the search input field.\n * @param {HTMLElement} recentHistoryBox - the search history listbox\n */\nconst onMouseDown = (searchField, recentHistoryBox) => {\n const li = listbox.getSelectedElementByAria(searchField, recentHistoryBox);\n if (!li) return;\n\n const { id, selectedText } = listbox.getTextAndIdFromListEl(li);\n if (!selectedText) return;\n\n if (isDeleteSearchHistoryButton(li)) {\n // this is only needed in mouseup, keydown is already in input field\n document.addEventListener(\n 'mouseup',\n () => { searchField.focus(); },\n { once: true }\n );\n deleteAllRecentSearches(recentHistoryBox, searchField);\n } else {\n listbox.dispatchTermSelectedEvent(searchField, selectedText, id);\n }\n};\n\n/**\n * Helper method that retrieves the configured property for number of saved recent search entries.\n * Range of the configured value (x) is 0 < x < 26.\n * capacity cannot be set to null, 0, or > 25 entries via configuration.\n * @returns {number} Configured number within the range of . Has default value of 10\n */\nconst getCustomMaxCapacityOrDefault = () => {\n const { recentSearchMaxSize = 10 } = getScriptData('gnav-data') || {};\n const useFallback = recentSearchMaxSize === null\n || (recentSearchMaxSize * 1) < 1\n || (recentSearchMaxSize * 1) > 25;\n return useFallback ? 10 : (recentSearchMaxSize * 1);\n};\n\n/* init */\nconst init = (selectors) => {\n const searchElems = getDomElems(selectors);\n if (searchElems === null) return;\n setStateOnInit();\n /* build state */\n let recentSearches = getRecentSearches();\n const maxCapacity = getCustomMaxCapacityOrDefault();\n /* Handles edge case if the capacity is lowered, but user has previous history */\n if (recentSearches.length > maxCapacity) {\n setRecentSearches(recentSearches.slice(0, maxCapacity));\n recentSearches = getRecentSearches();\n }\n /* find and set up related elems */\n const { searchForm, recentHistoryBox } = searchElems;\n const searchField = searchForm.querySelector('[data-js=search-field]');\n searchField.setAttribute('aria-activedescendant', '');\n const ariaLiveRegion = searchForm.querySelector(`${LISTBOX.ARIA_LIVE.SELECTOR}`);\n Object.assign(recentSearchState, searchElems, {\n ariaLiveRegion, recentSearches, searchField, maxCapacity,\n });\n /* Event Listeners */\n // all keyboard events occur in the input field (focus is visual only)\n searchField.addEventListener('focus', onFocus.bind(null, recentHistoryBox));\n searchField.addEventListener('blur', onBlur.bind(null, ariaLiveRegion, recentHistoryBox));\n searchField.addEventListener('keyup', onKeyUp.bind(null, recentHistoryBox));\n searchField.addEventListener(\n 'keydown',\n onKeyDown.bind(null, searchField, recentHistoryBox)\n );\n // mouse events occur on the actual listbox\n recentHistoryBox.addEventListener(\n 'mousedown',\n onMouseDown.bind(null, searchField, recentHistoryBox)\n );\n // in either scenario, make search the search term gets added to history\n searchForm.addEventListener('submit', () => {\n addToSearchHistory(searchField, window);\n });\n document.addEventListener('termSelected', () => {\n addToSearchHistory(searchField, window);\n });\n};\nexport default init;\n","/**\n * Search Field in Masthead\n * Optional part of Global Navigation. Includes conditional initialization of autosuggest,\n * and recent search history.\n */\n\nimport searchInit from '../search';\nimport suggestInit from '../suggest';\nimport recentSearchInit from '../recents';\nimport getScriptData from '../../../util/getScriptData';\n\nconst {\n enableAutosuggest = false,\n enableRecentSearch = false,\n showSearch = false,\n searchAction = '',\n useConstructorAutosuggest = false,\n} = getScriptData('gnav-data') || {};\n\nexport function app(win) {\n if (showSearch) {\n /* init the search bar (expand / contract) */\n searchInit({\n masthead: '[data-js=masthead]',\n searchForm: '[data-js=search-form]',\n searchField: '[data-js=search-field]',\n clearButton: '[data-js=clear-button]',\n searchButton: '[data-js=search-button]',\n searchCancel: '[data-js=search-cancel]',\n });\n }\n if (enableAutosuggest && !(useConstructorAutosuggest && searchAction === '/search')) {\n /* init listboxes - autosuggest & recent search history */\n suggestInit({\n searchField: '[data-js=search-field]',\n suggestionBox: '[data-js=suggestion-box]',\n suggestionList: '[data-js=suggestion-list]',\n searchForm: '[data-js=search-form]',\n });\n }\n if (enableRecentSearch) {\n recentSearchInit({\n recentHistoryBox: '[data-js=recent-search-box]',\n searchForm: '[data-js=search-form]',\n });\n }\n\n return win;\n}\n\nexport function main(win = window) {\n if (win.document.readyState === 'loading') {\n // Loading hasn't finished yet\n win.document.addEventListener('DOMContentLoaded', app.bind(null, win));\n } else {\n // `DOMContentLoaded` has already fired\n app(win);\n }\n}\n","import '../../../../../util/global-shim';\nimport { main } from './main';\nimport '../../../../../../style/navigation/global/components/search/base-search.scss';\n/**\n * This is the main js entry point for search component(s)\n *\n * @param win Window object. Pass in to allow for window stubbing.\n * @returns {Window}\n */\nmain(window);\n"],"names":["$TypeError","validateArgumentsLength","passed","required","defineBuiltIn","require$$0","uncurryThis","require$$1","toString","require$$2","require$$3","$URLSearchParams","URLSearchParamsPrototype","append","$delete","forEach","push","params","name","length","$value","entries","v","k","key","value","index","dindex","found","entriesLength","entry","getAll","$has","values","DESCRIPTORS","defineBuiltInAccessor","count","conditionalAnalytics","searchHistory","searchTermType","linkName","searchRecentQuerySource","autosuggest","natural","getSearchType","ariaAD","startsWith","getTermIndex","match","lastString","Number","isNaN","getConditionalAnalytics","searchType","condAnalytics","analytics","autoSuggestPosition","getSumbitAnalytics","searchTerm","events","searchTermClicked","handleSearchFormSubmissionAnalytics","config","document","location","hostname","console","group","Object","log","groupEnd","analyticsCustomClickHandler","getSearchParam","param","URLSearchParams","window","search","get","showClearButton","searchField","clearButton","removeAttribute","setAttribute","hideClearButton","setClearButtonVisibility","enableSearchButton","searchButton","trim","classList","add","remove","clearSearchField","inputElem","focus","analyticsLogged","handleAnalytics","ariaActivedescendant","getAttribute","handleTermSelected","searchForm","e","preventDefault","submit","init","selectors","searchElems","getDomElems","addEventListener","sliceSize","cleanSearchResult","item","replace","getStartsWithData","data","cleanedSearchTerm","filter","getIncludesData","includes","partitionData","cleanSearchTerm","map","term","optionalSpecialCharacterPattern","i","len","optionalSpecialCharacterRegExp","RegExp","matches","resultTitle","specialCharacterRegExp","toLowerCase","cleanFetchedItems","fetchedItems","filterResults","state","newState","startsWithData","includesData","concat","filteredResults","slice","SEARCH_HISTORY","LI_ID","UL_ID","LOCAL_STORAGE_KEY","SELECTOR","RECENTLY_SELECTED","DELETE","ID","CSS","TEXT","TITLE","AUTOSUGGEST","URL","FALLBACK","LISTBOX","VISUAL_FOCUS","LIST_ITEM","ARIA_LIVE","DIRECTIONS","ALL_LI","preventDefaultOnKeyDown","getKeyCode","code","ARROW_DOWN","keyCode","ARROW_UP","END","getUpdatedIndexOnArrowDown","currentIndex","getUpdatedIndexOnArrowUp","setSearchField","cleanListEntries","listEntries","elem","resetListbox","getIndexFromElement","id","wordsArr","split","setVisualFocus","listItem","shouldUpdateVisibility","listboxElem","newValue","dataset","visible","visibleValue","addMouseMoveEventListeners","dynamicElem","enterCallback","leaveCallback","termSelectedEvent","CustomEvent","bubbles","cancelable","getTextAndIdFromListEl","li","HTMLLIElement","selectedText","textContent","getSelectedElementByAria","listbox","querySelector","updateAriaAndSearchTerm","dispatchTermSelectedEvent","dispatchEvent","autosuggestListboxIsOpen","suggestionBox","getAutosuggestTarget","autosuggestTarget","targetUrl","getScriptData","fetchData","fetchPoint","fetch","then","response","ok","status","url","error","json","catch","getInnerHtml","getAriaLiveTextForResults","resultCount","onMouseLeave","target","ariaLiveRegion","querySelectorAll","contains","onMouseEnter","appendResults","results","suggestionList","ul","innerHTML","createElement","className","appendChild","setSuggestionBoxVisibility","isVisible","parentElement","onFocus","onBlur","onMouseDown","onKeyUp","keyCodeVal","updatedIndex","ESCAPE","setSelectionRange","HOME","ARROW_LEFT","ARROW_RIGHT","onKeyDown","ENTER","NUMPAD_ENTER","onInput","assign","bind","recentSearchState","maxCapacity","recentSearches","setStateOnInit","recentHistoryBox","getRecentSearches","win","JSON","parse","localStorage","getItem","clearSearchHistory","removeItem","setRecentSearches","setItem","stringify","addToSearchHistory","pop","isDeleteSearchHistoryButton","elemToCheck","firstElementChild","getAriaLiveTextForTotalResults","listEntryCount","getAllListEntries","createListEntryWithChildElem","childTagName","elemPropsToSet","listEntry","keys","appendRecentSearches","clearHistoryListItem","type","tabIndex","setRecentSearchBoxVisibility","deleteAllRecentSearches","recentSearchListboxShouldShow","handleKeyUp","innerText","visibilityChanged","ariaLive","once","getCustomMaxCapacityOrDefault","recentSearchMaxSize","enableAutosuggest","enableRecentSearch","showSearch","searchAction","useConstructorAutosuggest","app","searchInit","masthead","searchCancel","suggestInit","recentSearchInit","main","readyState"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}