@samline/autocomplete 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/LICENSE.md +1 -1
- package/README.md +208 -32
- package/dist/browser/global.global.js +505 -274
- package/dist/browser/global.global.js.map +1 -1
- package/dist/browser/index.cjs +663 -0
- package/dist/browser/index.cjs.map +1 -0
- package/dist/browser/index.d.cts +31 -0
- package/dist/browser/index.d.ts +31 -0
- package/dist/browser/index.js +24 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/chunk-4IPBCQDZ.js +218 -0
- package/dist/chunk-4IPBCQDZ.js.map +1 -0
- package/dist/chunk-5UZVFHB4.js +70 -0
- package/dist/chunk-5UZVFHB4.js.map +1 -0
- package/dist/chunk-AD7T42HJ.js +1 -0
- package/dist/chunk-AD7T42HJ.js.map +1 -0
- package/dist/chunk-PPDQPLPE.js +1 -0
- package/dist/chunk-PPDQPLPE.js.map +1 -0
- package/dist/chunk-U5JYDGKW.js +403 -0
- package/dist/chunk-U5JYDGKW.js.map +1 -0
- package/dist/core/index.cjs +181 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +31 -0
- package/dist/core/index.d.ts +31 -0
- package/dist/core/index.js +22 -0
- package/dist/core/index.js.map +1 -0
- package/dist/index.cjs +527 -274
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -69
- package/dist/index.d.ts +20 -69
- package/dist/index.js +54 -405
- package/dist/index.js.map +1 -1
- package/dist/render-B38UXYCT.d.ts +7 -0
- package/dist/render-WD69VMUs.d.cts +7 -0
- package/dist/styles.css +19 -9
- package/dist/types-CPvjhqjb.d.cts +118 -0
- package/dist/types-CPvjhqjb.d.ts +118 -0
- package/dist/vanilla/index.cjs +598 -0
- package/dist/vanilla/index.cjs.map +1 -0
- package/dist/vanilla/index.d.cts +11 -0
- package/dist/vanilla/index.d.ts +11 -0
- package/dist/vanilla/index.js +13 -0
- package/dist/vanilla/index.js.map +1 -0
- package/package.json +19 -4
- package/dist/browser/global.d.ts +0 -61
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
2
|
+
var AutocompleteBundle = (() => {
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -21,19 +21,66 @@ var Autocomplete = (() => {
|
|
|
21
21
|
// src/browser/global.ts
|
|
22
22
|
var global_exports = {};
|
|
23
23
|
__export(global_exports, {
|
|
24
|
-
autocomplete: () =>
|
|
24
|
+
autocomplete: () => autocomplete2,
|
|
25
25
|
available: () => available2,
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
browser: () => browser,
|
|
27
|
+
default: () => global_default,
|
|
28
|
+
destroyAutocomplete: () => destroyAutocomplete2,
|
|
29
|
+
destroyAutocompletes: () => destroyAutocompletes2,
|
|
30
|
+
getAutocomplete: () => getAutocomplete2,
|
|
31
|
+
getAutocompletes: () => getAutocompletes2,
|
|
32
|
+
newAutocomplete: () => newAutocomplete2
|
|
28
33
|
});
|
|
29
34
|
|
|
30
|
-
// src/
|
|
31
|
-
var
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
// src/constants.ts
|
|
36
|
+
var DEFAULT_QUERY_PARAM = "q";
|
|
37
|
+
var DEFAULT_MIN_LENGTH = 2;
|
|
38
|
+
var DEFAULT_DEBOUNCE = 250;
|
|
39
|
+
var DEFAULT_MAX_RESULTS = 8;
|
|
40
|
+
var DEFAULT_CACHE_SIZE = 50;
|
|
41
|
+
var DEFAULT_CACHE_TTL = 3e5;
|
|
42
|
+
var POPUP_ATTRIBUTE = "data-autocomplete-popup";
|
|
43
|
+
var LIST_ATTRIBUTE = "data-autocomplete-list";
|
|
44
|
+
var OPTION_ATTRIBUTE = "data-autocomplete-option";
|
|
45
|
+
var STATUS_ATTRIBUTE = "data-autocomplete-status";
|
|
46
|
+
var LIVE_ATTRIBUTE = "data-autocomplete-live";
|
|
47
|
+
var HIGHLIGHT_ATTRIBUTE = "data-autocomplete-highlight";
|
|
48
|
+
|
|
49
|
+
// src/core/cache.ts
|
|
50
|
+
var createCache = ({ max = DEFAULT_CACHE_SIZE, ttl = DEFAULT_CACHE_TTL } = {}, now = Date.now) => {
|
|
51
|
+
const entries = /* @__PURE__ */ new Map();
|
|
52
|
+
const get = (key) => {
|
|
53
|
+
const entry = entries.get(key);
|
|
54
|
+
if (!entry) return void 0;
|
|
55
|
+
entries.delete(key);
|
|
56
|
+
if (entry.expires <= now()) return void 0;
|
|
57
|
+
entries.set(key, entry);
|
|
58
|
+
return entry.value;
|
|
59
|
+
};
|
|
60
|
+
const set = (key, value) => {
|
|
61
|
+
entries.delete(key);
|
|
62
|
+
entries.set(key, { value, expires: now() + ttl });
|
|
63
|
+
while (entries.size > max) {
|
|
64
|
+
const oldest = entries.keys().next();
|
|
65
|
+
if (oldest.done) break;
|
|
66
|
+
entries.delete(oldest.value);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
return {
|
|
70
|
+
get,
|
|
71
|
+
set,
|
|
72
|
+
clear: () => entries.clear(),
|
|
73
|
+
get size() {
|
|
74
|
+
return entries.size;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
35
77
|
};
|
|
78
|
+
|
|
79
|
+
// src/core/source.ts
|
|
36
80
|
var parseJsonResponse = async (response) => response.json();
|
|
81
|
+
var invalidPayloadError = () => new TypeError(
|
|
82
|
+
"Autocomplete response does not contain an array. Configure mapResponse(payload, response, query)."
|
|
83
|
+
);
|
|
37
84
|
var mapCommonResponse = (payload) => {
|
|
38
85
|
if (Array.isArray(payload)) return payload;
|
|
39
86
|
if (!payload || typeof payload !== "object") throw invalidPayloadError();
|
|
@@ -43,86 +90,200 @@ var Autocomplete = (() => {
|
|
|
43
90
|
if (Array.isArray(record.data)) return record.data;
|
|
44
91
|
throw invalidPayloadError();
|
|
45
92
|
};
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
93
|
+
var fromEndpoint = ({
|
|
94
|
+
endpoint,
|
|
95
|
+
queryParam = DEFAULT_QUERY_PARAM,
|
|
96
|
+
requestInit = {},
|
|
97
|
+
parseResponse = parseJsonResponse,
|
|
98
|
+
mapResponse = mapCommonResponse
|
|
99
|
+
}) => {
|
|
100
|
+
if (!endpoint) throw new TypeError("Autocomplete requires an endpoint.");
|
|
101
|
+
return async (query, { signal, input }) => {
|
|
102
|
+
const resolved = typeof endpoint === "function" ? endpoint(query, input) : endpoint;
|
|
103
|
+
const url = new URL(resolved, document.baseURI);
|
|
104
|
+
if (queryParam !== null) url.searchParams.set(queryParam, query);
|
|
105
|
+
const init = typeof requestInit === "function" ? requestInit(query, input) : requestInit;
|
|
106
|
+
const response = await fetch(url, { ...init, signal });
|
|
107
|
+
if (!response.ok) throw new Error(`Autocomplete request failed with HTTP ${response.status}.`);
|
|
108
|
+
const payload = await parseResponse(response, query);
|
|
109
|
+
const result = await mapResponse(payload, response, query);
|
|
110
|
+
if (!Array.isArray(result))
|
|
111
|
+
throw new TypeError("Autocomplete mapResponse must return an array.");
|
|
112
|
+
return result;
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// src/core/state.ts
|
|
117
|
+
var DEFAULT_MESSAGES = {
|
|
118
|
+
loading: "Searching...",
|
|
119
|
+
empty: "No results",
|
|
120
|
+
error: "Search failed",
|
|
121
|
+
results: ({ count }) => count === 1 ? "1 result available" : `${count} results available`
|
|
122
|
+
};
|
|
123
|
+
var resolveMessage = (message, context) => typeof message === "function" ? message(context) : message;
|
|
124
|
+
var readField = (suggestion, keys) => {
|
|
53
125
|
if (typeof suggestion === "string") return suggestion;
|
|
54
126
|
if (!suggestion || typeof suggestion !== "object") return String(suggestion ?? "");
|
|
55
127
|
const record = suggestion;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
128
|
+
const key = keys.find((name) => record[name] !== void 0 && record[name] !== null);
|
|
129
|
+
return key === void 0 ? "" : String(record[key]);
|
|
130
|
+
};
|
|
131
|
+
var getDefaultLabel = (suggestion) => readField(suggestion, ["label", "value", "title", "name"]);
|
|
132
|
+
var getDefaultValue = (suggestion) => readField(suggestion, ["value", "label", "title", "name"]);
|
|
133
|
+
var getDefaultId = (suggestion, index) => {
|
|
59
134
|
if (!suggestion || typeof suggestion !== "object") return index;
|
|
60
135
|
return suggestion.id ?? index;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (!
|
|
136
|
+
};
|
|
137
|
+
var assertNonNegativeInteger = (value, name) => {
|
|
138
|
+
if (value !== void 0 && (!Number.isInteger(value) || value < 0)) {
|
|
139
|
+
throw new TypeError(`Autocomplete ${name} must be a non-negative integer.`);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
var assertPositiveInteger = (value, name) => {
|
|
143
|
+
if (value !== void 0 && (!Number.isInteger(value) || value < 1)) {
|
|
144
|
+
throw new TypeError(`Autocomplete ${name} must be an integer greater than zero.`);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
var validateOptions = (options) => {
|
|
148
|
+
const hasSource = options.source !== void 0;
|
|
149
|
+
const hasEndpoint = options.endpoint !== void 0;
|
|
150
|
+
if (hasSource && hasEndpoint) {
|
|
151
|
+
throw new TypeError("Autocomplete accepts either a source or an endpoint, not both.");
|
|
152
|
+
}
|
|
153
|
+
if (!hasSource && !options.endpoint) {
|
|
154
|
+
throw new TypeError("Autocomplete requires a source or an endpoint.");
|
|
155
|
+
}
|
|
156
|
+
if (hasSource && !Array.isArray(options.source) && typeof options.source !== "function") {
|
|
157
|
+
throw new TypeError("Autocomplete source must be an array or a function.");
|
|
158
|
+
}
|
|
64
159
|
assertNonNegativeInteger(options.minLength, "minLength");
|
|
65
160
|
assertNonNegativeInteger(options.debounce, "debounce");
|
|
66
|
-
|
|
67
|
-
|
|
161
|
+
assertPositiveInteger(options.maxResults, "maxResults");
|
|
162
|
+
if (typeof options.cache === "object") {
|
|
163
|
+
assertPositiveInteger(options.cache.max, "cache.max");
|
|
164
|
+
assertNonNegativeInteger(options.cache.ttl, "cache.ttl");
|
|
68
165
|
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// src/core/text.ts
|
|
169
|
+
var COMBINING_MARKS = /\p{M}/gu;
|
|
170
|
+
var WHITESPACE = /\s+/;
|
|
171
|
+
var normalizeText = (value) => value.normalize("NFD").replace(COMBINING_MARKS, "").toLowerCase();
|
|
172
|
+
var getTerms = (query, normalize) => Array.from(new Set(normalize(query).split(WHITESPACE).filter(Boolean)));
|
|
173
|
+
var filterSuggestions = (suggestions, query, { getText, normalize = normalizeText }) => {
|
|
174
|
+
const terms = getTerms(query, normalize);
|
|
175
|
+
if (terms.length === 0) return [...suggestions];
|
|
176
|
+
return suggestions.filter((suggestion) => {
|
|
177
|
+
const text = normalize(getText(suggestion));
|
|
178
|
+
return terms.every((term) => text.includes(term));
|
|
179
|
+
});
|
|
180
|
+
};
|
|
181
|
+
var highlight = (text, query, normalize = normalizeText) => {
|
|
182
|
+
const terms = getTerms(query, normalize);
|
|
183
|
+
if (terms.length === 0 || text === "") return text === "" ? [] : [{ text, match: false }];
|
|
184
|
+
let normalized = "";
|
|
185
|
+
const starts = [];
|
|
186
|
+
const ends = [];
|
|
187
|
+
let offset = 0;
|
|
188
|
+
for (const char of text) {
|
|
189
|
+
const piece = normalize(char);
|
|
190
|
+
if (piece === "" && ends.length > 0) ends[ends.length - 1] = offset + char.length;
|
|
191
|
+
normalized += piece;
|
|
192
|
+
for (let index = 0; index < piece.length; index += 1) {
|
|
193
|
+
starts.push(offset);
|
|
194
|
+
ends.push(offset + char.length);
|
|
195
|
+
}
|
|
196
|
+
offset += char.length;
|
|
73
197
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
198
|
+
const ranges = [];
|
|
199
|
+
for (const term of terms) {
|
|
200
|
+
let found = normalized.indexOf(term);
|
|
201
|
+
while (found !== -1) {
|
|
202
|
+
ranges.push([starts[found], ends[found + term.length - 1]]);
|
|
203
|
+
found = normalized.indexOf(term, found + 1);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (ranges.length === 0) return [{ text, match: false }];
|
|
207
|
+
ranges.sort((a, b) => a[0] - b[0]);
|
|
208
|
+
const merged = [];
|
|
209
|
+
for (const range of ranges) {
|
|
210
|
+
const last = merged[merged.length - 1];
|
|
211
|
+
if (last && range[0] <= last[1]) last[1] = Math.max(last[1], range[1]);
|
|
212
|
+
else merged.push([range[0], range[1]]);
|
|
213
|
+
}
|
|
214
|
+
const parts = [];
|
|
215
|
+
let cursor = 0;
|
|
216
|
+
for (const [start, end] of merged) {
|
|
217
|
+
if (start > cursor) parts.push({ text: text.slice(cursor, start), match: false });
|
|
218
|
+
parts.push({ text: text.slice(start, end), match: true });
|
|
219
|
+
cursor = end;
|
|
220
|
+
}
|
|
221
|
+
if (cursor < text.length) parts.push({ text: text.slice(cursor), match: false });
|
|
222
|
+
return parts;
|
|
223
|
+
};
|
|
80
224
|
|
|
81
|
-
// src/
|
|
82
|
-
|
|
225
|
+
// src/vanilla/dom.ts
|
|
226
|
+
var resolveInput = (target) => {
|
|
83
227
|
const element = typeof target === "string" ? document.querySelector(target) : target;
|
|
84
228
|
if (!(element instanceof HTMLInputElement)) {
|
|
85
229
|
throw new TypeError("Autocomplete requires an HTMLInputElement or a valid selector.");
|
|
86
230
|
}
|
|
87
231
|
return element;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
232
|
+
};
|
|
233
|
+
var sanitizeId = (value) => String(value).replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
234
|
+
var restoreAttribute = (element, name, value) => {
|
|
235
|
+
if (value === null) element.removeAttribute(name);
|
|
236
|
+
else element.setAttribute(name, value);
|
|
237
|
+
};
|
|
238
|
+
var renderHighlight = (element, parts) => {
|
|
239
|
+
for (const part of parts) {
|
|
240
|
+
if (!part.match) {
|
|
241
|
+
element.append(document.createTextNode(part.text));
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
const mark = document.createElement("mark");
|
|
245
|
+
mark.setAttribute(HIGHLIGHT_ATTRIBUTE, "");
|
|
246
|
+
mark.textContent = part.text;
|
|
247
|
+
element.append(mark);
|
|
96
248
|
}
|
|
97
|
-
|
|
98
|
-
|
|
249
|
+
};
|
|
250
|
+
var VISUALLY_HIDDEN = "position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0";
|
|
99
251
|
|
|
100
|
-
// src/
|
|
252
|
+
// src/vanilla/render.ts
|
|
253
|
+
var RESTORED_ATTRIBUTES = [
|
|
254
|
+
"role",
|
|
255
|
+
"autocomplete",
|
|
256
|
+
"aria-autocomplete",
|
|
257
|
+
"aria-controls",
|
|
258
|
+
"aria-expanded",
|
|
259
|
+
"aria-activedescendant"
|
|
260
|
+
];
|
|
101
261
|
var instanceCount = 0;
|
|
102
|
-
|
|
262
|
+
var isAbortError = (error) => error instanceof DOMException && error.name === "AbortError";
|
|
263
|
+
var autocomplete = (target, options) => {
|
|
103
264
|
validateOptions(options);
|
|
104
265
|
const input = resolveInput(target);
|
|
105
266
|
const instanceId = `autocomplete-${++instanceCount}`;
|
|
106
267
|
const messages = { ...DEFAULT_MESSAGES, ...options.messages };
|
|
107
|
-
const
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
searchOnFocus: options.searchOnFocus ?? true,
|
|
121
|
-
onSelect: options.onSelect,
|
|
122
|
-
onError: options.onError
|
|
123
|
-
};
|
|
268
|
+
const localSuggestions = Array.isArray(options.source) ? options.source : null;
|
|
269
|
+
const getLabel = options.getLabel ?? getDefaultLabel;
|
|
270
|
+
const getValue = options.getValue ?? getDefaultValue;
|
|
271
|
+
const getId = options.getId ?? getDefaultId;
|
|
272
|
+
const normalize = options.normalize ?? normalizeText;
|
|
273
|
+
const minLength = options.minLength ?? (localSuggestions ? 1 : DEFAULT_MIN_LENGTH);
|
|
274
|
+
const debounce = options.debounce ?? (localSuggestions ? 0 : DEFAULT_DEBOUNCE);
|
|
275
|
+
const maxResults = options.maxResults ?? DEFAULT_MAX_RESULTS;
|
|
276
|
+
const searchOnFocus = options.searchOnFocus ?? true;
|
|
277
|
+
const highlightEnabled = options.highlight ?? true;
|
|
278
|
+
const source = localSuggestions ? null : typeof options.source === "function" ? options.source : fromEndpoint(options);
|
|
279
|
+
const cache = source && options.cache !== false ? createCache(typeof options.cache === "object" ? options.cache : {}) : null;
|
|
280
|
+
const popup = document.createElement("div");
|
|
124
281
|
const list = document.createElement("div");
|
|
282
|
+
const status = document.createElement("div");
|
|
283
|
+
const live = document.createElement("div");
|
|
125
284
|
const originalAttributes = /* @__PURE__ */ new Map();
|
|
285
|
+
const label = input.labels?.[0] ?? null;
|
|
286
|
+
const originalLabelId = label?.getAttribute("id") ?? null;
|
|
126
287
|
let suggestions = [];
|
|
127
288
|
let activeIndex = -1;
|
|
128
289
|
let selected = null;
|
|
@@ -131,145 +292,220 @@ var Autocomplete = (() => {
|
|
|
131
292
|
let requestSequence = 0;
|
|
132
293
|
let destroyed = false;
|
|
133
294
|
let suppressFocusSearch = false;
|
|
295
|
+
popup.hidden = true;
|
|
296
|
+
popup.setAttribute(POPUP_ATTRIBUTE, "");
|
|
134
297
|
list.id = `${instanceId}-listbox`;
|
|
135
298
|
list.hidden = true;
|
|
136
299
|
list.role = "listbox";
|
|
137
|
-
list.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
300
|
+
list.setAttribute(LIST_ATTRIBUTE, "");
|
|
301
|
+
status.hidden = true;
|
|
302
|
+
status.setAttribute(STATUS_ATTRIBUTE, "");
|
|
303
|
+
status.setAttribute("aria-hidden", "true");
|
|
304
|
+
live.role = "status";
|
|
305
|
+
live.setAttribute("aria-live", "polite");
|
|
306
|
+
live.setAttribute("aria-atomic", "true");
|
|
307
|
+
live.setAttribute(LIVE_ATTRIBUTE, "");
|
|
308
|
+
live.style.cssText = VISUALLY_HIDDEN;
|
|
309
|
+
if (label) {
|
|
310
|
+
if (!label.id) label.id = `${instanceId}-label`;
|
|
311
|
+
list.setAttribute("aria-labelledby", label.id);
|
|
147
312
|
}
|
|
313
|
+
for (const name of RESTORED_ATTRIBUTES) originalAttributes.set(name, input.getAttribute(name));
|
|
148
314
|
input.role = "combobox";
|
|
149
315
|
input.autocomplete = "off";
|
|
150
316
|
input.setAttribute("aria-autocomplete", "list");
|
|
151
317
|
input.setAttribute("aria-controls", list.id);
|
|
152
318
|
input.setAttribute("aria-expanded", "false");
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
319
|
+
popup.append(list, status);
|
|
320
|
+
input.insertAdjacentElement("afterend", popup);
|
|
321
|
+
popup.insertAdjacentElement("afterend", live);
|
|
322
|
+
const dispatch = (name, detail) => {
|
|
323
|
+
input.dispatchEvent(new CustomEvent(name, { bubbles: true, detail }));
|
|
324
|
+
};
|
|
325
|
+
const announce = (message) => {
|
|
326
|
+
live.textContent = message;
|
|
327
|
+
};
|
|
328
|
+
const cancel = () => {
|
|
329
|
+
clearTimeout(debounceTimer);
|
|
330
|
+
debounceTimer = void 0;
|
|
331
|
+
requestSequence += 1;
|
|
332
|
+
abortController?.abort();
|
|
333
|
+
abortController = null;
|
|
334
|
+
};
|
|
335
|
+
const updateActiveOption = () => {
|
|
336
|
+
const elements = list.querySelectorAll(`[${OPTION_ATTRIBUTE}]`);
|
|
337
|
+
elements.forEach((element, index) => {
|
|
338
|
+
const active2 = index === activeIndex;
|
|
339
|
+
element.dataset.active = String(active2);
|
|
340
|
+
element.setAttribute("aria-selected", String(active2));
|
|
341
|
+
});
|
|
342
|
+
const active = elements.item(activeIndex);
|
|
343
|
+
if (!active) {
|
|
344
|
+
input.removeAttribute("aria-activedescendant");
|
|
178
345
|
return;
|
|
179
346
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
347
|
+
input.setAttribute("aria-activedescendant", active.id);
|
|
348
|
+
active.scrollIntoView({ block: "nearest" });
|
|
349
|
+
};
|
|
350
|
+
const close = () => {
|
|
351
|
+
activeIndex = -1;
|
|
352
|
+
popup.hidden = true;
|
|
353
|
+
list.hidden = true;
|
|
354
|
+
status.hidden = true;
|
|
355
|
+
input.setAttribute("aria-expanded", "false");
|
|
356
|
+
input.removeAttribute("aria-activedescendant");
|
|
357
|
+
updateActiveOption();
|
|
358
|
+
};
|
|
359
|
+
const dismiss = () => {
|
|
360
|
+
cancel();
|
|
361
|
+
close();
|
|
362
|
+
};
|
|
363
|
+
const renderStatus = (state, query) => {
|
|
364
|
+
if (destroyed) return;
|
|
365
|
+
const message = resolveMessage(messages[state], { query, count: 0 });
|
|
366
|
+
list.replaceChildren();
|
|
367
|
+
list.hidden = true;
|
|
368
|
+
status.textContent = message;
|
|
369
|
+
status.setAttribute(STATUS_ATTRIBUTE, state);
|
|
370
|
+
status.hidden = false;
|
|
371
|
+
popup.hidden = false;
|
|
372
|
+
input.setAttribute("aria-expanded", "false");
|
|
373
|
+
input.removeAttribute("aria-activedescendant");
|
|
374
|
+
if (state !== "loading") announce(message);
|
|
375
|
+
};
|
|
376
|
+
const select = (index) => {
|
|
377
|
+
const suggestion = suggestions[index];
|
|
378
|
+
if (!suggestion) return;
|
|
379
|
+
selected = suggestion.data;
|
|
380
|
+
input.value = suggestion.value;
|
|
381
|
+
dismiss();
|
|
382
|
+
dispatch("autocomplete:select", {
|
|
383
|
+
suggestion: suggestion.data,
|
|
384
|
+
label: suggestion.label,
|
|
385
|
+
value: suggestion.value
|
|
386
|
+
});
|
|
387
|
+
options.onSelect?.(suggestion.data, input);
|
|
388
|
+
};
|
|
389
|
+
const handleOptionPointerDown = (event) => {
|
|
390
|
+
event.preventDefault();
|
|
391
|
+
select(Number(event.currentTarget.dataset.index));
|
|
392
|
+
if (document.activeElement !== input) {
|
|
393
|
+
suppressFocusSearch = true;
|
|
394
|
+
input.focus({ preventScroll: true });
|
|
395
|
+
suppressFocusSearch = false;
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
const handleOptionPointerEnter = (event) => {
|
|
399
|
+
activeIndex = Number(event.currentTarget.dataset.index);
|
|
400
|
+
updateActiveOption();
|
|
401
|
+
};
|
|
402
|
+
const renderSuggestions = (query) => {
|
|
403
|
+
const fragment = document.createDocumentFragment();
|
|
404
|
+
suggestions.forEach((suggestion, index) => {
|
|
405
|
+
const option = document.createElement("div");
|
|
406
|
+
const parts = highlightEnabled ? highlight(suggestion.label, query, normalize) : [{ text: suggestion.label, match: false }];
|
|
407
|
+
option.id = suggestion.id;
|
|
408
|
+
option.role = "option";
|
|
409
|
+
option.setAttribute(OPTION_ATTRIBUTE, "");
|
|
410
|
+
option.dataset.index = String(index);
|
|
411
|
+
option.setAttribute("aria-selected", "false");
|
|
412
|
+
renderHighlight(option, parts);
|
|
413
|
+
options.renderOption?.(option, suggestion.data, {
|
|
414
|
+
query,
|
|
415
|
+
index,
|
|
416
|
+
label: suggestion.label,
|
|
417
|
+
highlight: parts
|
|
418
|
+
});
|
|
419
|
+
option.addEventListener("pointerdown", handleOptionPointerDown);
|
|
420
|
+
option.addEventListener("pointerenter", handleOptionPointerEnter);
|
|
421
|
+
fragment.append(option);
|
|
422
|
+
});
|
|
423
|
+
list.replaceChildren(fragment);
|
|
424
|
+
list.hidden = false;
|
|
425
|
+
status.hidden = true;
|
|
426
|
+
popup.hidden = false;
|
|
427
|
+
input.setAttribute("aria-expanded", "true");
|
|
428
|
+
};
|
|
429
|
+
const normalizeSuggestion = (suggestion, index) => ({
|
|
430
|
+
id: `${instanceId}-option-${sanitizeId(getId(suggestion, index))}`,
|
|
431
|
+
label: String(getLabel(suggestion)),
|
|
432
|
+
value: String(getValue(suggestion)),
|
|
433
|
+
data: suggestion
|
|
434
|
+
});
|
|
435
|
+
const showResults = (query, result, cached) => {
|
|
436
|
+
if (destroyed) return;
|
|
437
|
+
suggestions = result.slice(0, maxResults).map(normalizeSuggestion);
|
|
438
|
+
activeIndex = -1;
|
|
439
|
+
if (suggestions.length === 0) renderStatus("empty", query);
|
|
440
|
+
else {
|
|
441
|
+
renderSuggestions(query);
|
|
442
|
+
announce(resolveMessage(messages.results, { query, count: suggestions.length }));
|
|
443
|
+
}
|
|
444
|
+
dispatch("autocomplete:load", {
|
|
445
|
+
query,
|
|
446
|
+
suggestions: suggestions.map((suggestion) => suggestion.data),
|
|
447
|
+
cached
|
|
448
|
+
});
|
|
449
|
+
};
|
|
450
|
+
const filterLocal = (items, query) => {
|
|
451
|
+
const filter = options.filter;
|
|
452
|
+
return filter ? items.filter((item) => filter(item, query)) : filterSuggestions(items, query, { getText: getLabel, normalize });
|
|
453
|
+
};
|
|
454
|
+
const search = async (query = input.value.trim()) => {
|
|
455
|
+
if (destroyed || query.length < minLength) {
|
|
184
456
|
close();
|
|
185
457
|
return;
|
|
186
458
|
}
|
|
187
459
|
cancel();
|
|
188
460
|
const sequence = ++requestSequence;
|
|
461
|
+
if (localSuggestions) {
|
|
462
|
+
showResults(query, filterLocal(localSuggestions, query), false);
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
const hit = cache?.get(query);
|
|
466
|
+
if (hit) {
|
|
467
|
+
showResults(query, hit, true);
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
189
470
|
const controller = new AbortController();
|
|
190
471
|
abortController = controller;
|
|
191
|
-
renderStatus(
|
|
472
|
+
renderStatus("loading", query);
|
|
192
473
|
dispatch("autocomplete:loadstart", { query });
|
|
193
474
|
try {
|
|
194
|
-
const
|
|
195
|
-
if (!
|
|
196
|
-
const payload = await settings.parseResponse(response, query);
|
|
197
|
-
const result = await settings.mapResponse(payload, response, query);
|
|
198
|
-
if (!Array.isArray(result))
|
|
199
|
-
throw new TypeError("Autocomplete mapResponse must return an array.");
|
|
475
|
+
const result = await source(query, { signal: controller.signal, input });
|
|
476
|
+
if (!Array.isArray(result)) throw new TypeError("Autocomplete source must return an array.");
|
|
200
477
|
if (sequence !== requestSequence) return;
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
if (suggestions.length === 0) renderStatus(messages.empty, "status", "empty");
|
|
204
|
-
else renderSuggestions();
|
|
205
|
-
dispatch("autocomplete:load", {
|
|
206
|
-
query,
|
|
207
|
-
suggestions: suggestions.map((suggestion) => suggestion.data)
|
|
208
|
-
});
|
|
478
|
+
cache?.set(query, result);
|
|
479
|
+
showResults(query, result, false);
|
|
209
480
|
} catch (error) {
|
|
210
|
-
if (isAbortError(error) || sequence !== requestSequence) return;
|
|
481
|
+
if (isAbortError(error) || sequence !== requestSequence || destroyed) return;
|
|
211
482
|
suggestions = [];
|
|
212
483
|
activeIndex = -1;
|
|
213
|
-
renderStatus(
|
|
484
|
+
renderStatus("error", query);
|
|
214
485
|
dispatch("autocomplete:error", { query, error });
|
|
215
|
-
|
|
486
|
+
options.onError?.(error, input);
|
|
216
487
|
} finally {
|
|
217
488
|
if (sequence === requestSequence) abortController = null;
|
|
218
489
|
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
option.dataset.index = String(index);
|
|
239
|
-
option.setAttribute("aria-selected", "false");
|
|
240
|
-
settings.renderOption?.(option, suggestion.data);
|
|
241
|
-
option.addEventListener("pointerdown", handleOptionPointerDown);
|
|
242
|
-
option.addEventListener("pointerenter", handleOptionPointerEnter);
|
|
243
|
-
fragment.append(option);
|
|
244
|
-
});
|
|
245
|
-
list.append(fragment);
|
|
246
|
-
open();
|
|
247
|
-
}
|
|
248
|
-
function renderStatus(message, role, state) {
|
|
249
|
-
const element = document.createElement("div");
|
|
250
|
-
element.role = role;
|
|
251
|
-
element.textContent = message;
|
|
252
|
-
element.dataset.autocompleteStatus = state;
|
|
253
|
-
list.replaceChildren(element);
|
|
254
|
-
open(true);
|
|
255
|
-
}
|
|
256
|
-
function open(allowStatus = false) {
|
|
257
|
-
if (destroyed || !allowStatus && suggestions.length === 0) return;
|
|
258
|
-
list.hidden = false;
|
|
259
|
-
input.setAttribute("aria-expanded", "true");
|
|
260
|
-
}
|
|
261
|
-
function close() {
|
|
262
|
-
activeIndex = -1;
|
|
263
|
-
list.hidden = true;
|
|
264
|
-
input.setAttribute("aria-expanded", "false");
|
|
265
|
-
input.removeAttribute("aria-activedescendant");
|
|
266
|
-
updateActiveOption();
|
|
267
|
-
}
|
|
268
|
-
function dismiss() {
|
|
269
|
-
cancel();
|
|
270
|
-
close();
|
|
271
|
-
}
|
|
272
|
-
function clear() {
|
|
490
|
+
};
|
|
491
|
+
const scheduleSearch = () => {
|
|
492
|
+
clearTimeout(debounceTimer);
|
|
493
|
+
const query = input.value.trim();
|
|
494
|
+
if (selected !== null) {
|
|
495
|
+
selected = null;
|
|
496
|
+
dispatch("autocomplete:clear", { query });
|
|
497
|
+
}
|
|
498
|
+
if (query.length < minLength) {
|
|
499
|
+
dismiss();
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
if (debounce === 0) {
|
|
503
|
+
void search(query);
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
debounceTimer = setTimeout(() => void search(query), debounce);
|
|
507
|
+
};
|
|
508
|
+
const clear = () => {
|
|
273
509
|
const hadSelection = selected !== null;
|
|
274
510
|
cancel();
|
|
275
511
|
suggestions = [];
|
|
@@ -277,70 +513,36 @@ var Autocomplete = (() => {
|
|
|
277
513
|
selected = null;
|
|
278
514
|
input.value = "";
|
|
279
515
|
close();
|
|
516
|
+
announce("");
|
|
280
517
|
if (hadSelection) dispatch("autocomplete:clear", { query: "" });
|
|
281
|
-
}
|
|
282
|
-
|
|
518
|
+
};
|
|
519
|
+
const moveActiveOption = (direction) => {
|
|
283
520
|
if (list.hidden || suggestions.length === 0) return;
|
|
284
521
|
activeIndex = activeIndex === -1 ? direction > 0 ? 0 : suggestions.length - 1 : (activeIndex + direction + suggestions.length) % suggestions.length;
|
|
285
522
|
updateActiveOption();
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
option.setAttribute("aria-selected", String(active2));
|
|
293
|
-
});
|
|
294
|
-
const active = options2.item(activeIndex);
|
|
295
|
-
if (!active) {
|
|
296
|
-
input.removeAttribute("aria-activedescendant");
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
input.setAttribute("aria-activedescendant", active.id);
|
|
300
|
-
active.scrollIntoView({ block: "nearest" });
|
|
301
|
-
}
|
|
302
|
-
function select(index) {
|
|
303
|
-
const suggestion = suggestions[index];
|
|
304
|
-
if (!suggestion) return;
|
|
305
|
-
selected = suggestion.data;
|
|
306
|
-
input.value = suggestion.value;
|
|
307
|
-
dismiss();
|
|
308
|
-
dispatch("autocomplete:select", {
|
|
309
|
-
suggestion: suggestion.data,
|
|
310
|
-
label: suggestion.label,
|
|
311
|
-
value: suggestion.value
|
|
312
|
-
});
|
|
313
|
-
settings.onSelect?.(suggestion.data, input);
|
|
314
|
-
}
|
|
315
|
-
function dispatch(name, detail) {
|
|
316
|
-
input.dispatchEvent(new CustomEvent(name, { bubbles: true, detail }));
|
|
317
|
-
}
|
|
318
|
-
function cancel() {
|
|
319
|
-
window.clearTimeout(debounceTimer);
|
|
320
|
-
debounceTimer = void 0;
|
|
321
|
-
requestSequence += 1;
|
|
322
|
-
abortController?.abort();
|
|
323
|
-
abortController = null;
|
|
324
|
-
}
|
|
325
|
-
function handleFocus() {
|
|
523
|
+
};
|
|
524
|
+
const handleInput = (event) => {
|
|
525
|
+
if (event.isComposing) return;
|
|
526
|
+
scheduleSearch();
|
|
527
|
+
};
|
|
528
|
+
const handleFocus = () => {
|
|
326
529
|
if (suppressFocusSearch) return;
|
|
327
|
-
if (
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
function handleKeydown(event) {
|
|
530
|
+
if (searchOnFocus && input.value.trim().length >= minLength) scheduleSearch();
|
|
531
|
+
};
|
|
532
|
+
const handleKeydown = (event) => {
|
|
533
|
+
const listOpen = !list.hidden && suggestions.length > 0;
|
|
332
534
|
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
333
|
-
if (
|
|
535
|
+
if (!listOpen) return;
|
|
334
536
|
event.preventDefault();
|
|
335
537
|
moveActiveOption(event.key === "ArrowDown" ? 1 : -1);
|
|
336
538
|
return;
|
|
337
539
|
}
|
|
338
|
-
if (event.key === "Enter" &&
|
|
540
|
+
if (event.key === "Enter" && listOpen && activeIndex >= 0) {
|
|
339
541
|
event.preventDefault();
|
|
340
542
|
select(activeIndex);
|
|
341
543
|
return;
|
|
342
544
|
}
|
|
343
|
-
if ((event.key === "Home" || event.key === "End") &&
|
|
545
|
+
if ((event.key === "Home" || event.key === "End") && listOpen) {
|
|
344
546
|
event.preventDefault();
|
|
345
547
|
activeIndex = event.key === "Home" ? 0 : suggestions.length - 1;
|
|
346
548
|
updateActiveOption();
|
|
@@ -352,26 +554,11 @@ var Autocomplete = (() => {
|
|
|
352
554
|
return;
|
|
353
555
|
}
|
|
354
556
|
if (event.key === "Tab") dismiss();
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
event.
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
if (document.activeElement !== input) {
|
|
361
|
-
suppressFocusSearch = true;
|
|
362
|
-
input.focus({ preventScroll: true });
|
|
363
|
-
suppressFocusSearch = false;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
function handleOptionPointerEnter(event) {
|
|
367
|
-
const element = event.currentTarget;
|
|
368
|
-
activeIndex = Number(element.dataset.index);
|
|
369
|
-
updateActiveOption();
|
|
370
|
-
}
|
|
371
|
-
function handleDocumentPointerDown(event) {
|
|
372
|
-
if (event.target !== input && !list.contains(event.target)) dismiss();
|
|
373
|
-
}
|
|
374
|
-
function destroy3() {
|
|
557
|
+
};
|
|
558
|
+
const handleDocumentPointerDown = (event) => {
|
|
559
|
+
if (event.target !== input && !popup.contains(event.target)) dismiss();
|
|
560
|
+
};
|
|
561
|
+
const destroy = () => {
|
|
375
562
|
if (destroyed) return;
|
|
376
563
|
destroyed = true;
|
|
377
564
|
cancel();
|
|
@@ -380,9 +567,12 @@ var Autocomplete = (() => {
|
|
|
380
567
|
input.removeEventListener("focus", handleFocus);
|
|
381
568
|
input.removeEventListener("keydown", handleKeydown);
|
|
382
569
|
document.removeEventListener("pointerdown", handleDocumentPointerDown);
|
|
383
|
-
|
|
570
|
+
popup.remove();
|
|
571
|
+
live.remove();
|
|
572
|
+
cache?.clear();
|
|
384
573
|
originalAttributes.forEach((value, name) => restoreAttribute(input, name, value));
|
|
385
|
-
|
|
574
|
+
if (label) restoreAttribute(label, "id", originalLabelId);
|
|
575
|
+
};
|
|
386
576
|
input.addEventListener("input", handleInput);
|
|
387
577
|
input.addEventListener("compositionend", scheduleSearch);
|
|
388
578
|
input.addEventListener("focus", handleFocus);
|
|
@@ -390,48 +580,89 @@ var Autocomplete = (() => {
|
|
|
390
580
|
document.addEventListener("pointerdown", handleDocumentPointerDown);
|
|
391
581
|
return {
|
|
392
582
|
element: input,
|
|
583
|
+
popupElement: popup,
|
|
393
584
|
listElement: list,
|
|
585
|
+
statusElement: status,
|
|
586
|
+
liveElement: live,
|
|
394
587
|
options,
|
|
395
588
|
search,
|
|
396
589
|
close: dismiss,
|
|
397
590
|
clear,
|
|
398
591
|
cancel,
|
|
592
|
+
clearCache: () => cache?.clear(),
|
|
399
593
|
getSelected: () => selected,
|
|
400
|
-
destroy
|
|
594
|
+
destroy
|
|
401
595
|
};
|
|
402
|
-
}
|
|
403
|
-
function isAbortError(error) {
|
|
404
|
-
return error instanceof DOMException && error.name === "AbortError";
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// src/api/create-autocomplete.ts
|
|
408
|
-
function createAutocomplete(target, options) {
|
|
409
|
-
return createAutocompleteController(target, options);
|
|
410
|
-
}
|
|
596
|
+
};
|
|
411
597
|
|
|
412
598
|
// src/browser/registry.ts
|
|
413
599
|
var available = /* @__PURE__ */ Object.create(null);
|
|
414
|
-
|
|
415
|
-
const
|
|
416
|
-
if (!
|
|
417
|
-
available[input.id]?.destroy();
|
|
418
|
-
const controller = createAutocomplete(input, options);
|
|
419
|
-
available[input.id] = controller;
|
|
420
|
-
return controller;
|
|
421
|
-
}
|
|
422
|
-
function destroy(id) {
|
|
423
|
-
available[id]?.destroy();
|
|
600
|
+
var removeRegistration = (id) => {
|
|
601
|
+
const entry = available[id];
|
|
602
|
+
if (!entry) return;
|
|
424
603
|
delete available[id];
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
604
|
+
entry.destroy();
|
|
605
|
+
};
|
|
606
|
+
var newAutocomplete = ({
|
|
607
|
+
id,
|
|
608
|
+
options
|
|
609
|
+
}) => {
|
|
610
|
+
if (!id) {
|
|
611
|
+
console.error("Autocomplete ID is required");
|
|
612
|
+
return null;
|
|
613
|
+
}
|
|
614
|
+
const input = document.getElementById(id);
|
|
615
|
+
if (!(input instanceof HTMLInputElement)) {
|
|
616
|
+
console.warn(`Autocomplete input with ID ${id} not found`);
|
|
617
|
+
return null;
|
|
618
|
+
}
|
|
619
|
+
removeRegistration(id);
|
|
620
|
+
const controller = autocomplete(input, options);
|
|
621
|
+
const destroy = controller.destroy;
|
|
622
|
+
const registered = {
|
|
623
|
+
...controller,
|
|
624
|
+
destroy: () => {
|
|
625
|
+
if (available[id] === registered) delete available[id];
|
|
626
|
+
destroy();
|
|
627
|
+
}
|
|
628
|
+
};
|
|
629
|
+
available[id] = registered;
|
|
630
|
+
return registered;
|
|
631
|
+
};
|
|
632
|
+
var getAutocomplete = (id) => available[id] ?? null;
|
|
633
|
+
var getAutocompletes = () => ({
|
|
634
|
+
...available
|
|
635
|
+
});
|
|
636
|
+
var destroyAutocomplete = (target) => {
|
|
637
|
+
if (typeof target === "string") return removeRegistration(target);
|
|
638
|
+
const entry = Object.entries(available).find(([, controller]) => controller.element === target);
|
|
639
|
+
if (entry) removeRegistration(entry[0]);
|
|
640
|
+
};
|
|
641
|
+
var destroyAutocompletes = () => Object.keys(available).forEach(removeRegistration);
|
|
642
|
+
var Autocomplete = {
|
|
643
|
+
autocomplete,
|
|
644
|
+
newAutocomplete,
|
|
645
|
+
getAutocomplete,
|
|
646
|
+
getAutocompletes,
|
|
647
|
+
destroyAutocomplete,
|
|
648
|
+
destroyAutocompletes,
|
|
430
649
|
available
|
|
431
650
|
};
|
|
432
651
|
|
|
433
652
|
// src/browser/global.ts
|
|
434
|
-
|
|
653
|
+
if (typeof globalThis !== "undefined") {
|
|
654
|
+
;
|
|
655
|
+
globalThis.Autocomplete = Autocomplete;
|
|
656
|
+
}
|
|
657
|
+
var browser = Autocomplete;
|
|
658
|
+
var autocomplete2 = Autocomplete.autocomplete;
|
|
659
|
+
var newAutocomplete2 = Autocomplete.newAutocomplete;
|
|
660
|
+
var getAutocomplete2 = Autocomplete.getAutocomplete;
|
|
661
|
+
var getAutocompletes2 = Autocomplete.getAutocompletes;
|
|
662
|
+
var destroyAutocomplete2 = Autocomplete.destroyAutocomplete;
|
|
663
|
+
var destroyAutocompletes2 = Autocomplete.destroyAutocompletes;
|
|
664
|
+
var available2 = Autocomplete.available;
|
|
665
|
+
var global_default = Autocomplete;
|
|
435
666
|
return __toCommonJS(global_exports);
|
|
436
667
|
})();
|
|
437
668
|
//# sourceMappingURL=global.global.js.map
|