import { HistorySuggestion } from '../../utils/suggestions'; import { InputHistory } from './history'; import { HistoryStore } from './store'; import { AutocompletableInput } from '../input'; import { delegate } from 'utils/events'; /** * Stores a set of histories identified by their unique IDs. */ class InputHistoriesPool { private histories = new Map(); load(historyId: string): InputHistory { const existing = this.histories.get(historyId); if (existing) { return existing; } const store = new HistoryStore(historyId); const newHistory = new InputHistory(store); this.histories.set(historyId, newHistory); return newHistory; } } const histories = new InputHistoriesPool(); export function listen() { // Only load the history for the input element when it gets focused. document.addEventListener('focusin', event => { const input = AutocompletableInput.fromElement(event.target); if (!input?.historyId) { return; } histories.load(input.historyId); }); delegate(document, 'submit', { '[data-autocomplete-history-id]'(_event, target) { const input = AutocompletableInput.fromElement(target); if (!input || !input.hasHistory()) { return; } histories.load(input.historyId).write(input.snapshot.trimmedValue); }, }); } /** * Returns suggestions based on history for the input. Unless the `limit` is * specified as an argument, it will return the maximum number of suggestions * allowed by the input. */ export function listSuggestions(input: AutocompletableInput, limit?: number): HistorySuggestion[] { if (!input.hasHistory()) { return []; } const value = input.snapshot.trimmedValue.toLowerCase(); return histories .load(input.historyId) .listSuggestions(value, limit ?? input.maxSuggestions) .map(content => new HistorySuggestion(content, value.length)); }