import { Controller } from "stimulus"; import { Liquid } from "liquidjs"; const lunr = require("lunr"); require("lunr-languages/lunr.stemmer.support")(lunr); require("lunr-languages/lunr.es")(lunr); export default class extends Controller { static targets = ["q"]; get q() { if (!this.hasQTarget) return; if (!this.qTarget.value.trim().length === 0) return; return this.qTarget.value.trim().replaceAll(/[:~\*\^\+\-]/gi, ""); } connect() { const q = new URLSearchParams(window.location.search).get("q")?.trim(); if (q) { this.qTarget.value = q; this.search(); } } async search(event) { // Detiene el envío del formulario if (event) { event.preventDefault(); event.stopPropagation(); } this.formDisable = true; // Obtiene el término de búsqueda const q = this.q; // Si no hay término de búsqueda, no hay búsqueda if (q) { // Trae el índice de búsqueda await this.fetch(); // Hasta que no haya índice no buscamos nada, esto evita que se // aprete enter dos veces y se fallen cosas. if (!window.index) return; } const main = document.querySelector("main"); const results = window.index .search(q) .map((r) => window.data.find((a) => a.id == r.ref)); const site = window.site; const template = window.templates.results; const html = await this.engine.parseAndRender(template, { q, site, results, }); const title = `${site.i18n.search.title} - ${q}`; const query = new URLSearchParams({ q }); window.history.pushState({ q }, title, `?${query.toString()}`); document.title = title; main.innerHTML = html; this.formDisable = false; } async fetch() { // Solo permite descargar uno a la vez if (this.fetching) return; this.fetching = true; let response; // Si no existe el índice, lo descarga y procesa Lunr if (!window.data) { response = await fetch("data.json"); window.data = await response.json(); } if (!window.index) { response = await fetch("idx.json"); const idx = await response.json(); window.index = lunr.Index.load(idx); } // Permitir volver a ejecutar this.fetching = false; } set formDisable(disable) { this.element.elements.forEach((x) => (x.disabled = disable)); } /* * Liquid renderer * * @return Liquid */ get engine() { if (!window.liquid) window.liquid = new Liquid(); return window.liquid; } }