1const _ = { 2 /** 3 * URL pour les requêtes de facettes 4 */ 5 ajaxFacetsUrl: "/recherche/recherche-facettes.json", 6 /** 7 * URL pour les requêtes de résultats 8 */ 9 ajaxResultsUrl: "/recherche/recherche-resultats.html", 10 /** 11 * URL pour les requêtes de suggestions 12 */ 13 ajaxSuggestionsUrl: "/recherche/recherche-suggestions.json", 14 /** 15 * Activer ou désactiver l'autocomplétion dans la barre de 16 */ 17 suggestionsEnabled: !1, 18 /** 19 * Si on veut utiliser la version compacte et combinée des paramètre dans l'URL. 20 * Si on active les options "mask" et "concat" de l'extension SOLR de TYPO3. 21 */ 22 compactQueryStringEnabled: !1, 23 /** 24 * Activer ou désactiver le mode debug 25 * - active logExecutionTimeInConsole() : pour les requêtes pour des suggestions dans l'autocomplétion 26 */ 27 debug: !1, 28 /** 29 * Si on veut appliquer un filtre par défaut pour les résultats 30 * Pour les sites autres que Calendrier, on va probablement toujours être en "none". 31 * 32 * "none" : on recherche dans tous les résultats. 33 * "futureOnly" : on recherche dans les résultats dont la date est supérieur à la date actuelle. 34 */ 35 defaultFilter: "none", 36 /** 37 * Si on veut appliquer une option de facette par défaut pour les résultats. 38 * ex. types:udem_article 39 */ 40 defaultSelectedOption: "", 41 /** 42 * Champ SOLR utilisé pour appliquer le filtre "futureOnly" 43 */ 44 futureOnlyFilterField: "date", 45 /** 46 * ID du conteneur de suggestions dans le header 47 */ 48 headerSuggestionContainerId: "#tx-udem-solr-header-suggestions-container", 49 /** 50 * ID de l'input de recherche dans l'entête 51 */ 52 headerSearchInputId: "#menu-search-input", 53 /** 54 * Libellés (et traduction) que l'on peut modifier dans les configs 55 * Il y a aussi des traductions dans le module locale.js. On pourrait les fusionner(todo). 56 * Pour le moment, ça permet de remplacer "Documents" par "Activités" pour le calendrier. 57 */ 58 locale: { 59 suggestionsDocumentsLabel: { 60 en: "Documents", 61 fr: "Documents" 62 } 63 }, 64 /** 65 * Langue d'affichage du site 66 */ 67 lng: "fr", 68 /** 69 * Mobile breakpoint 70 */ 71 mobileBreakpoint: 576, 72 /** 73 * Nombre de caractères minimum pour afficher des suggestions 74 */ 75 minSearchLength: 2, 76 /** 77 * Nombre de caractères maximum pour faire des recherches et pour afficher des suggestions 78 * 125 : basé sur la longueur des titres des News et des Events en BD 79 */ 80 maxSearchLength: 125, 81 /** 82 * Hook qui permet de définir une fonction pour modifier le html des résultats juste avant qu'ils soient affichés 83 */ 84 parseResultsFn: null, 85 /** 86 * URL de la page de résultats 87 */ 88 resultListingUrl: "/recherche", 89 /** 90 * Paramètre GET utilisé pour les requêtes SOLR 91 */ 92 solrGetParameter: "tx_solr", 93 /** 94 * Le nombre de suggestions à afficher par facette 95 */ 96 suggestionsFacetLimit: 5, 97 /** 98 * Ouvrir les suggestions de documents dans un nouvel onglet. 99 */ 100 suggestionsOpenInNewTab: !1, 101 /** 102 * PID du dossier des enregistrements. 103 * On veut afficher seulement des suggestions à partir de ce dossier. 104 * Nécessaire, car le middleware bypass l'environnement de TYPO3 et les configurations de l'extension SOLR défini en typoscript. 105 * */ 106 suggestionsRootline: "0", 107 /** 108 * Type de suggestions à afficher si l'autocomplétion est activée 109 * document : suggestions de documents / résultats 110 * facet : suggestions de facettes 111 * search : suggestions de recherche. Lorsqu'on utilise le middleware d'UdemSolr, on n'a pas de suggestions de recherche (search). 112 * terms : Suggestion à partir de la fonction "Terms" de Solr. Ex. Profs pour UdemNouvelles 113 */ 114 suggestionsTypes: ["document", "facet", "profs", "search", "terms"], 115 /** 116 * Si on veut appliquer un filtre par défaut différent pour les suggestions. Pas sûr que ça soit utile, mais au cas... 117 * Pour les sites autres que Calendrier, on va probablement toujours être en "none". 118 * 119 * "none" : on fait des suggestions à partir de tous les résultats. 120 * "futureOnly" : on fait des suggestions à partir des résultats futurs seulement. 121 * "matchSearchDefault" : on fait des suggestions avec la même configuration que pour la recherche (defaultFilter). 122 */
123 suggestionsDefaultFilter: "matchDefaultFilter", 124 /** 125 * SI on applique un filtre supplémentaire en JS sur les suggestions qu'on reçoit 126 */ 127 suggestionsJsFilterEnabled: !0, 128 /** 129 * Si on veut obtenir les suggestions en utilisant le middleware d'UdemSolr au lieu d'utiliser l'extension SOLR, 130 * Si on utilise le middleware : 131 * - on change le paramètre "tx_solr[queryString]" pour "tx_udem_suggestions" 132 * - on ajoute le paramètre "rootline". 133 */ 134 useSuggestionsMiddleware: !0 135}; 136let d = {}; 137function we(e) { 138 B(e); 139} 140function a(e) { 141 if (d[e] === void 0) 142 throw new Error(`La configuration "${e}" n'existe pas.`); 143 return d[e]; 144} 145function G(e) { 146 const t = a("lng"); 147 return d.locale[e] && d.locale[e][t] !== void 0 ? d.locale[e][t] : e; 148} 149function B(e) { 150 d = { ..._, ...e }; 151} 152let M = 0; 153function j(e) { 154 return btoa(encodeURIComponent(e)); 155} 156async function x(e, t) { 157 const n = await fetch(e, { 158 method: "GET", 159 signal: t 160 }); 161 if (!n.ok) 162 throw new Error("FetchResponseError"); 163 return n.text(); 164} 165function K(e) { 166 return (/* @__PURE__ */ new Date()).getTime() - e; 167} 168function Fe(e) { 169 return String(e).replace(/[^\w. ]/gi, function(t) { 170 return "&#" + t.charCodeAt(0) + ";"; 171 }); 172} 173function J(e) { 174 return String(e).replace(/[<>&]/g, function(t) { 175 return "&#" + t.charCodeAt(0) + ";"; 176 }); 177} 178function g(e, t, n = !1) { 179 n && console.log(e + " - " + K(t) + "ms"); 180} 181function Ee(e, t) { 182 const n = e.dataset.url; 183 if (!n) 184 return; 185 e.classList.contains("document") && a("suggestionsOpenInNewTab") || t.ctrlKey || t.metaKey ? window.open(n, "_blank", "noopener") : window.location.href = n; 186} 187function h(e, t = !0) { 188 return t ? Q(e.normalize("NFD").replace(/[\u0300-\u036f]/g, "")) : e.normalize("NFD").replace(/[\u0300-\u036f]/g, ""); 189} 190function Q(e) { 191 if (typeof e != "string") 192 throw new TypeError("Le texte doit être une chaîne de caractères."); 193 const t = /[â`â]/g; 194 return e.replace(t, "'"); 195} 196function ve(e, t) { 197 let s = new URL(window.location.href).searchParams.get(e); 198 return s ? s.replace(/</g, "<").replace(/>/g, ">") : t; 199} 200function Ce(e) { 201 window.history.pushState("", "", window.location.href.split("?")[0] + e); 202} 203function Te(e, t) { 204 let n = new URL(window.location.href); 205 n.searchParams.set(e, t), window.history.pushState("", "", n); 206} 207function W(e) { 208 M = e; 209} 210function m() { 211 return M; 212} 213const v = { 214 error: { 215 en: "An error happened.", 216 fr: "Une erreur est survenue." 217 }, 218 result: { 219 en: "result", 220 fr: "résultat" 221 }, 222 results: { 223 en: "results", 224 fr: "résultats" 225 }, 226 retry: { 227 en: "Retry", 228 fr: "Réessayer" 229 }, 230 /* Options sélectionnées */ 231 remove: { 232 en: "Remove", 233 fr: "Retirer" 234 }, 235 selectedOptionsKeyword: { 236 en: "Keyword: ", 237 fr: "Mot clé : " 238 }, 239 selectedOptionsRemoveAll: { 240 en: "Reset", 241 fr: "Réinitialiser" 242 }, 243 selectedOptionsSearchedTerm: { 244 en: "Search: ", 245 fr: "Recherche : " 246 }, 247 to: { 248 en: "to", 249 fr: "au" 250 }, 251 /* Suggestions */ 252 suggestionsDocumentsLabel: { 253 en: "Documents", 254 fr: "Documents" 255 }, 256 suggestionsProfessorsLabel: { 257 en: "Professors", 258 fr: "Professeurs" 259 }, 260 suggestionsRecherchesLabel: { 261 en: "Search", 262 fr: "Recherche" 263 } 264}; 265function q(e) { 266 const t = a("lng"); 267 return v[e] && v[e][t] ? v[e][t] : e; 268} 269const l = document.createElement("ul"); 270l.classList.add("suggestions-list"); 271function Y(e, t, n, s, r, i) { 272 let o, c, u; 273 if (e && ({ suggestions: o, documents: c, terms: u } = e), r.innerHTML = "", l.innerHTML = "", !(!o && !c && !t && !n)) 274 if (V(c, s), P(n, s), Z(o, s), X(t, s), P(u, s), l.children.length > 0) { 275 const p = document.createElement("div"); 276 p.classList.add("suggestions-list-outer"), p.appendChild(l), r.appendChild(p), g("Suggestions displayed", i, a("debug")); 277 } else 278 g("No suggestions to display", i, a("debug")); 279} 280function X(e, t) { 281 if (a("suggestionsTypes").includes("facet")) 282 for (const [s, r] of Object.entries(e.facets)) { 283 if (!r.includeInSuggestion) 284 continue; 285 let i = r.options.filter( 286 (o) => h(o.label.toLowerCase()).includes(h(t.toLowerCase())) && o.documentCount > 0 287 ); 288 i = i.slice(0, a("suggestionsFacetLimit")), i.length >
288 0 && (F(r.label), i.forEach((o) => { 289 const c = document.createElement("li"); 290 c.classList.add("suggestion", "facet"), c.dataset.facet = o.class, c.dataset.url = a("resultListingUrl") + "?" + s + "=" + o.value, c.ariaLabel = o.label, c.tabIndex = 0, c.innerHTML = `<span>${E(t, o.label)}</span>`, l.appendChild(c); 291 })); 292 } 293} 294function Z(e, t) { 295 !a("suggestionsTypes").includes("search") || !e || Object.keys(e).length === 0 || (F(q("suggestionsRecherchesLabel")), Object.entries(e).forEach(([s]) => { 296 const r = document.createElement("li"); 297 r.classList.add("suggestion", "recherche"), r.ariaLabel = "Suggestion de recherche", r.dataset.url = a("resultListingUrl") + "?q=" + option.value, r.tabIndex = 0, r.innerHTML = `<span>${E(t, s)}</span>`, l.appendChild(r); 298 })); 299} 300function V(e, t) { 301 const n = a("suggestionsTypes").includes("document"); 302 if (e = ee(t, e), !n || !e || e.length === 0) 303 return; 304 const s = G("suggestionsDocumentsLabel"); 305 s && F(s), e.forEach(({ link: r, title: i }) => { 306 const o = document.createElement("li"); 307 o.classList.add("suggestion", "document"), o.dataset.url = r, o.ariaLabel = i, o.tabIndex = 0, o.innerHTML = `<span>${E(t, i)}</span>`, l.appendChild(o); 308 }); 309} 310function P(e, t) { 311 const n = a("suggestionsTypes") || []; 312 if (!(!(n.includes("terms") || n.includes("profs")) || !e || e.length === 0)) 313 for (const [r, i] of Object.entries(e)) 314 i.length > 0 && (F(r), i.forEach((o) => { 315 const c = document.createElement("li"); 316 c.classList.add("suggestion", "term"), c.dataset.facetOptionClass = o.class, c.dataset.optionValue = o.optionValue, c.dataset.solrFacetName = o.solrFacetName, c.dataset.idFacet = o.idFacet, c.dataset.url = a("resultListingUrl") + "?" + o.solrFacetName + "=" + o.value, c.ariaLabel = o.label, c.tabIndex = 0, c.innerHTML = `<span>${E(t, o.label)} ${o.extraLabel ?? ""}</span>`, l.appendChild(c); 317 })); 318} 319function F(e) { 320 const t = document.createElement("li"); 321 t.classList.add("separator"), t.innerHTML = e, l.appendChild(t); 322} 323function E(e, t) { 324 const n = h(t.toLowerCase()), s = h(e.toLowerCase()), r = n.indexOf(s); 325 if (r === -1) 326 return t; 327 const i = `<span class="highlight">${t.substring(r, r + e.length)}</span>`; 328 return t.substring(0, r) + i + t.substring(r + e.length); 329} 330function ee(e, t) { 331 return t ? a("suggestionsJsFilterEnabled") ? t.filter(({ title: n }) => h(n.toLowerCase()).includes(h(e.toLowerCase()))) : t : []; 332} 333function te(e) { 334 return e.length > a("maxSearchLength") ? e.substring(0, a("maxSearchLength")) : e; 335} 336function I(e, t, n = !1) { 337 return t + a("solrGetParameter") + "[filter][" + e + "]=" + ne(n); 338} 339function ne(e) { 340 const t = a("futureOnlyFilterField"); 341 return e ? t + ":1900/01/01-2100/01/01" : t + ":" + se() + "-2100/01/01"; 342} 343function $(e, t) { 344 return t + a("solrGetParameter") + "[page]=" + e; 345} 346function se() { 347 const e = /* @__PURE__ */ new Date(), t = e.getFullYear(), n = (e.getMonth() + 1).toString().padStart(2, "0"), s = e.getDate().toString().padStart(2, "0"); 348 return `${t}/${n}/${s}`; 349} 350function xe(e) { 351 const t = e.querySelectorAll('input[type="radio"], input[type="checkbox"]'); 352 return Array.prototype.some.call(t, function(n) { 353 return n.checked; 354 }); 355} 356const b = []; 357let S = []; 358async function re(e, t) { 359 const n = e.replace(/&?tx_solr\[page\]=\d+/, ""), s = j(n), r = b[s] || null; 360 if (S.includes(s)) 361 return new Promise((i, o) => { 362 const c = setInterval(() => { 363 S.includes(s) || (clearInterval(c), i(b[s])); 364 }, 100); 365 }); 366 if (r) 367 return r; 368 try { 369 S.push(s); 370 const i = a("ajaxFacetsUrl") + n, o = await x(i, t), c = JSON.parse(o); 371 return b[s] = c, oe(), A(s), c; 372 } catch (i) { 373 i.name !== "AbortError" && console.error(i), A(s); 374 } 375} 376function A(e) { 377 S = S.filter((t) => t !== e); 378} 379function oe() { 380 const t = Object.keys(b); 381 if (t.length > 100) { 382 const n = t[0]; 383 delete b[n]; 384 } 385} 386async function ae(e = !0) { 387 const t = new AbortController().signal, s = a("defaultFilter") === "futureOnly" ? I(0, "?", e) + $(1, "&") : $(1, "?"); 388 return re(s, t); 389} 390let y = null, U = [], k = !1; 391function ie() { 392 y && !y.signal.aborted && (g("Aborting the previous request", m(), a("debug")), y.abort()); 393} 394async function ce() { 395 ie(), g("Fetching profs", m(), a("debug")), y = new AbortController(); 396 const e = y.signal, t = a("ajaxSuggestionsUrl") + "?tx_udem_suggestions_profs=count"; 397 try { 398 const n = await x(t, e); 399 if (!e.aborted) { 400 let s;
401 try { 402 s = JSON.parse(n), (typeof s != "object" || s === null) && (s = {}); 403 } catch { 404 s = {}; 405 } 406 return k = !0, s; 407 } 408 } catch (n) { 409 n.name !== "AbortError" && console.error(n); 410 } 411 return {}; 412} 413async function le(e) { 414 const t = q("suggestionsProfessorsLabel"); 415 if (!a("suggestionsTypes").includes("profs") || !e || e.trim().length === 0) 416 return { [t]: [] }; 417 const n = 15, s = await ge(), r = C(e.trim()), i = [], o = [], c = [], u = []; 418 for (const f of s) { 419 const N = C(f.lastName || ""), R = C(f.firstName || ""), O = `${R} ${N}`, D = `${N} ${R}`; 420 if (D.startsWith(r) ? i.push(f) : O.startsWith(r) ? o.push(f) : D.includes(r) ? u.push(f) : O.includes(r) && c.push(f), i.length >= n || i.length + o.length >= n) 421 break; 422 } 423 const p = [ 424 ...i, 425 ...o, 426 ...u, 427 ...c 428 ]; 429 return { 430 [t]: p.slice(0, n).map(ue) 431 }; 432} 433function ue(e) { 434 const { lastName: t, firstName: n, slug: s, unite: r } = e, i = "profs"; 435 return { 436 extraLabel: r ? ` (${r})` : "", 437 label: `${t}, ${n}`, 438 value: s, 439 optionValue: `${i}:${s}`, 440 solrFacetName: i, 441 idFacet: `facet${i}`, 442 class: `facet-option-${i}-${s}` 443 }; 444} 445async function ge() { 446 return a("suggestionsTypes").includes("profs") ? (k || (U = await ce()), U) : []; 447} 448function C(e) { 449 return e.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").trim(); 450} 451let L = null, z = !1; 452const w = []; 453function fe() { 454 L && !L.signal.aborted && (g("Aborting the previous request", m(), a("debug")), L.abort()); 455} 456async function de(e, t, n = !0) { 457 const s = j(e + n); 458 H() && Y(await he(e, t, n, s), await ae(n), await le(e), e, t, m()); 459} 460async function he(e, t, n, s) { 461 const r = w[s] || null; 462 if (r) 463 return r; 464 fe(), g("Fetching suggestions", m(), a("debug")), L = new AbortController(); 465 const i = L.signal; 466 let o = a("ajaxSuggestionsUrl") + "?" + pe() + "=" + encodeURIComponent(e) + me(1, n); 467 a("useSuggestionsMiddleware") && (o += "&rootline=" + a("suggestionsRootline")); 468 try { 469 const c = await x(o, i); 470 if (!i.aborted && (t.innerHTML = "", H())) { 471 const u = JSON.parse(c); 472 return w[s] = u, be(), u; 473 } 474 } catch (c) { 475 c.name !== "AbortError" && console.error(c); 476 } 477} 478function me(e, t) { 479 const n = a("suggestionsDefaultFilter"), s = a("defaultFilter"); 480 return n === "futureOnly" || n === "matchDefaultFilter" && s === "futureOnly" ? I(e, "&", t) : ""; 481} 482function H() { 483 return z; 484} 485function T(e) { 486 z = e; 487} 488function pe() { 489 return a("useSuggestionsMiddleware") ? "tx_udem_suggestions" : a("solrGetParameter") + "[queryString]"; 490} 491function be() { 492 const t = Object.keys(w); 493 if (t.length > 100) { 494 const n = t[0]; 495 delete w[n]; 496 } 497} 498function Ne(e, t) { 499 e.form.addEventListener("submit", (s) => { 500 s.preventDefault(), typeof t == "function" ? t(e.value) : (e.form.submit(), T(!1)); 501 }), e.addEventListener("keypress", (s) => { 502 s.key === "Enter" && e.form.dispatchEvent(new Event("submit", { cancelable: !0 })); 503 }); 504 let n = e.form.querySelector(".submit"); 505 n || (n = document.getElementById("menu-search-input-button")), n.addEventListener("click", (s) => { 506 s.preventDefault(), e.form.dispatchEvent(new Event("submit", { cancelable: !0 })); 507 }), e.addEventListener("input", () => { 508 e.value === "" && Se(); 509 }); 510} 511function Se() { 512 document.querySelectorAll(".facet-search-input").forEach((e) => { 513 e.value = ""; 514 }); 515} 516function Re(e) { 517 document.querySelectorAll(".facet-search-input").forEach((t) => { 518 t.value = e; 519 }); 520} 521function Oe(e, t) { 522 e.value = J(te(t)); 523} 524const ye = 100, Le = (e, t) => { 525 let n; 526 return (...s) => { 527 clearTimeout(n), n = setTimeout(() => { 528 e(...s); 529 }, t); 530 }; 531}, De = Le((e, t, n, s = !0) => { 532 const r = e.target.value.trim(); 533 r.length >= n && de(r, t, s); 534}, ye); 535function Pe(e, t) { 536 W(Date.now()), g("User is typing in the search input #" + e.id, m(), a("debug")); 537 const n = e.value.trim(); 538 n.length >= a("minSearchLength") && n.length < a("maxSearchLength") ? T(!0) : (t.innerHTML = "", T(!1)); 539} 540export { 541 Ee as a, 542 ae as b, 543 ge as c, 544 De as d, 545 xe as e, 546 Te as f, 547 a as g, 548 I as h, 549 we as i, 550 $ as j, 551 te as k, 552 Ce as l, 553 q as m, 554 Fe as n, 555 Ne as o, 556 x as p, 557 re as q, 558 Se as r, 559 Oe as s, 560 T as t, 561 ve as u, 562 Re as v, 563 Pe as w 564};
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.