PageSourceSearch

https://www.fiveguys.sa/wp-content/themes/five-guys/assets/js/static/algolia-autocomplete.js?ver=1781701843

js fiveguys.sa collected 2026-10-08 10:46:25 UTC 9,060 bytes, 266 lines download raw bytes

1(function ($) {
2  "use strict";
3
4  /**
5   * Algolia Autocomplete Config
6   */
7
8  // Localized Vars
9  var index_name_prefix = algolia_config.algolia_index_name_prefix;
10  var is_wpml_enabled = algolia_config.is_wpml_enabled;
11  var wp_locale = algolia_config.wp_locale;
12
13  // Apply dynamic prefix to each index name
14  var index_name_menu_item = `${index_name_prefix}posts_menu_item`;
15  var index_name_faq = `${index_name_prefix}posts_faq`;
16  var index_name_page = `${index_name_prefix}posts_page`;
17  var index_name_post = `${index_name_prefix}posts_post`;
18
19  $(window).on("load", function () {
20    let currentSearchQuery = "";
21
22    const templates = {
23      post: `
24        <a class="suggestion-link" href="{{ data.permalink }}" title="{{ data.post_title }}">
25          <div class="suggestion-post-attributes">
26            <span class="suggestion-post-title">{{{ data._highlightResult.post_title.value }}}</span>
27            {{{ data.snippet_content }}}
28          </div>
29        </a>
30      `,
31      empty: `
32        <div class="autocomplete-empty">
33          No results matched your query <span class="empty-query">"{{ data.query }}"</span>
34        </div>
35      `,
36    };
37
38    $("#tmpl-autocomplete-post-suggestion").html(templates.post);
39    $("#tmpl-autocomplete-empty").html(templates.empty);
40
41    const client = algoliasearch(algolia.application_id, algolia.search_api_key);
42
43    /** ORDER OF SECTIONS */
44    const desiredOrder = [
45      index_name_menu_item,
46      index_name_faq,
47      index_name_page,
48      index_name_post,
49    ];
50
51    /** INDEX → LABEL MAPPING */
52    const labelMap = {
53      [index_name_menu_item]: "Menu Items",
54      [index_name_faq]: "Frequently Asked Questions",
55      [index_name_page]: "Pages",
56      [index_name_post]: "Articles",
57    };
58
59    /** TEMPLATE RENDERER */
60    const suggestionTemplate = wp.template("autocomplete-post-suggestion");
61
62    /** -----------------------------------------------------------
63     * PROCESS HIT (highlight, snippets, permalink overrides)
64     * ---------------------------------------------------------- */
65    function processHit(hit) {
66      if (!hit.escaped) {
67        hit.escaped = true;
68
69        Object.keys(hit._highlightResult || {}).forEach((key) => {
70          const val = hit._highlightResult[key]?.value;
71          if (typeof val === "string") {
72            hit._highlightResult[key].value = _.escape(val)
73              .replace(/__ais-highlight__/g, "<em>")
74              .replace(/__\/ais-highlight__/g, "</em>");
75          }
76        });
77
78        Object.keys(hit._snippetResult || {}).forEach((key) => {
79          const val = hit._snippetResult[key]?.value;
80          if (typeof val === "string") {
81            hit._snippetResult[key].value = _.escape(val)
82              .replace(/__ais-highlight__/g, "<em>")
83              .replace(/__\/ais-highlight__/g, "</em>");
84          }
85        });
86
87        hit.snippet_content =
88          hit._snippetResult?.content?.value
89            ? `<div class="suggestion-snippet">${hit._snippetResult.content.value}</div>`
90            : "";
91      }
92
93      if (hit.post_type === "faq") {
94        hit.permalink = `${window.location.origin}/?s=${encodeURIComponent(
95          currentSearchQuery
96        )}&faq=${hit.post_id}`;
97      }
98
99      if (hit.post_type === "menu_item" && hit.menu_item_category) {
100        hit.permalink = hit.menu_item_category;
101      }
102
103      return suggestionTemplate(hit);
104    }
105
106    /** -----------------------------------------------------------
107     * ONE MULTI-INDEX REQUEST → MULTIPLE SECTION SOURCES
108     * ---------------------------------------------------------- */
109    function createSectionSources() {
110      return desiredOrder.map((indexName) => {
111        return {
112          indexName,
113          label: labelMap[indexName],
114          source: function (query, callback) {
115            currentSearchQuery = query;
116
117            if (!query || query.length < 2) {
118              callback([]);
119              return;
120            }
121
122            const query_map = desiredOrder.map((idx) => {
123              let index_config = {
124                indexName: idx,
125                query,
126                params: {
127                  hitsPerPage: 5,
128                  attributesToSnippet: ["content:10"],
129                  highlightPreTag: "__ais-highlight__",
130                  highlightPostTag: "__/ais-highlight__",
131                },
132              };
133
134              // Add local info if WPML is enabled
135              if ( is_wpml_enabled ) {
136                index_config.params.filters = 'wpml.locale:"' + wp_locale + '"';
137              }
138
139              return index_config;
140            });
141
142            const searchQueries = query_map;
143
144            client.search(searchQueries).then((res) => {
145              // Find this section’s index result
146              const sectionResult = res.results.find(
147                (r) => r.index === indexName
148              );
149
150              if (!sectionResult || !sectionResult.hits.length) {
151                callback([]);
152                return;
153              }
154
155              // Add __indexName and process each hit
156              const processed = sectionResult.hits.map((hit) => {
157                hit.__indexName = indexName;
158                return hit;
159              });
160
161              callback(processed);
162            });
163          },
164          templates: {
165            header: () =>
166              `<div class="autocomplete-section-label">${labelMap[indexName]}</div>`,
167
168            suggestion: (hit) => processHit(hit),
169
170            footer: () => {
171              const q = encodeURIComponent(currentSearchQuery);
172              const baseUrl = window.location.origin;
173              // console.log(labelMap[indexName])
174              // if (labelMap[indexName] === 'Menu Items') labelMap[indexName] = 'Menu Items';
175              // if (labelMap[indexName] === 'FAQs') labelMap[indexName] = 'FAQs';
176              // console.log(labelMap[indexName])
177              return `<div class="aa-suggestion show-all-link">
178                <a class="suggestion-link" href="${baseUrl}/?s=${q}&type=${labelMap[
179                indexName
180              ].toLowerCase()}">
181                  <strong>Show all ${labelMap[indexName]}</strong>
182                </a>
183              </div>`;
184            },
185          },
186        };
187      });
188    }
189
190    /** BUILD SOURCES */
191    const sources = createSectionSources();
192
193    /** -----------------------------------------------------------
194     * AUTOCOMPLETE INITIALIZATION
195     * ---------------------------------------------------------- */
196    $(algolia.autocomplete.input_selector).each(function () {
197      const $container = $(this).closest(".search-bar--wrapper--form");
198      if ($container.data("autocomplete-initialized")) return;
199      $container.data("autocomplete-initialized", true);
200
201      const autocomplete = algoliaAutocomplete(
202        this,
203        {
204          debug: algolia.debug,
205          hint: false,
206          openOnFocus: true,
207          appendTo: $container[0],
208          templates: { empty: wp.template("autocomplete-empty") },
209        },
210        sources
211      ).on("autocomplete:selected", (e, suggestion) => {
212        e.preventDefault();
213        window.location.assign(
214          suggestion.permalink || suggestion.posts_url
215        );
216      });
217
218      // Announce result count to screen readers via aria-live region
219      autocomplete.on('autocomplete:updated', function () {
220        const $liveRegion = $container.closest('.search-bar--wrapper').find('[aria-live]');
221        const query = autocomplete.autocomplete.getVal() || '';
222        const resultCount = $container.find('.aa-suggestion').not('.show-all-link').length;
223
224        if ( query.length < 2 ) {
225          $liveRegion.text('');
226        } else if ( resultCount > 0 ) {
227          $liveRegion.text( resultCount + ' suggestions available.' );
228        } else {
229          $liveRegion.text( $liveRegion.data('message') );
230        }
231      });
232
233      const resetSelectors =
234        ".js-dropdown-close, .search-reset, .mobile-tray-header .icon-button--close, .nav-search-dropdown.mobile .search-reset";
235
236      $(resetSelectors).on("click", function () {
237        autocomplete.autocomplete.setVal("");
238        autocomplete.autocomplete.close();
239
240        const wrapper = autocomplete.autocomplete.getWrapper();
241        if (wrapper) {
242          wrapper.style.display = "none";
243          wrapper.classList.remove("active");
244        }
245      });
246
247      const wrapper = autocomplete.autocomplete.getWrapper();
248      if (wrapper) {
249        const observer = new MutationObserver(() => {
250          const visible = window.getComputedStyle(wrapper).display !== "none";
251          wrapper.classList.toggle("active", visible);
252        });
253        observer.observe(wrapper, {
254          attributes: true,
255          attributeFilter: ["style"],
256        });
257      }
258    });
259
260    $(".search-submit").on("mousedown", function (e) {
261      e.preventDefault();
262      const input = $(this).closest(".search-form").find(".aa-input");
263      input.closest("form")[0].submit();
264    });
265  });
266})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.