2025-03-04 04:17:38 +00:00
|
|
|
import { HistorySuggestion } from '../../utils/suggestions';
|
|
|
|
import { InputHistory } from './history';
|
|
|
|
import { HistoryStore } from './store';
|
|
|
|
import { AutocompletableInput } from '../input';
|
2025-03-14 22:48:21 +00:00
|
|
|
import { delegate } from 'utils/events';
|
2025-03-04 04:17:38 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Stores a set of histories identified by their unique IDs.
|
|
|
|
*/
|
|
|
|
class InputHistoriesPool {
|
|
|
|
private histories = new Map<string, InputHistory>();
|
|
|
|
|
|
|
|
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);
|
|
|
|
});
|
|
|
|
|
2025-03-14 22:48:21 +00:00
|
|
|
delegate(document, 'submit', {
|
|
|
|
'[data-autocomplete-history-id]'(_event, target) {
|
|
|
|
const input = AutocompletableInput.fromElement(target);
|
|
|
|
if (!input || !input.hasHistory()) {
|
|
|
|
return;
|
|
|
|
}
|
2025-03-04 04:17:38 +00:00
|
|
|
|
2025-03-14 22:48:21 +00:00
|
|
|
histories.load(input.historyId).write(input.snapshot.trimmedValue);
|
|
|
|
},
|
2025-03-04 04:17:38 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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));
|
|
|
|
}
|