@pure-ds/core 0.7.48 → 0.7.50
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/dist/types/pds.d.ts +7 -5
- package/dist/types/public/assets/pds/components/pds-toaster.d.ts +4 -1
- package/dist/types/public/assets/pds/components/pds-toaster.d.ts.map +1 -1
- package/dist/types/src/js/common/toast.d.ts +9 -0
- package/dist/types/src/js/common/toast.d.ts.map +1 -1
- package/package.json +1 -1
- package/public/assets/js/app.js +2131 -5
- package/public/assets/js/app.js.map +7 -0
- package/public/assets/js/lit.js +1031 -3
- package/public/assets/js/lit.js.map +7 -0
- package/public/assets/js/pds-ask.js +464 -9
- package/public/assets/js/pds-ask.js.map +7 -0
- package/public/assets/js/pds-autocomplete.js +639 -7
- package/public/assets/js/pds-autocomplete.js.map +7 -0
- package/public/assets/js/pds-enhancers.js +1471 -1
- package/public/assets/js/pds-enhancers.js.map +7 -0
- package/public/assets/js/pds-manager.js +17568 -3384
- package/public/assets/js/pds-manager.js.map +7 -0
- package/public/assets/js/pds-toast.js +30 -1
- package/public/assets/js/pds-toast.js.map +7 -0
- package/public/assets/js/pds.js +1969 -2
- package/public/assets/js/pds.js.map +7 -0
- package/public/assets/pds/components/pds-toaster.js +25 -7
- package/public/assets/pds/core/pds-ask.js +464 -9
- package/public/assets/pds/core/pds-autocomplete.js +639 -7
- package/public/assets/pds/core/pds-enhancers.js +1471 -1
- package/public/assets/pds/core/pds-manager.js +17568 -3384
- package/public/assets/pds/core/pds-toast.js +30 -1
- package/public/assets/pds/core.js +1969 -2
- package/public/assets/pds/external/lit.js +1031 -3
- package/src/js/common/toast.js +8 -0
- package/src/js/pds-core/pds-generator.js +1 -1
- package/src/js/pds.d.ts +7 -5
|
@@ -1,7 +1,639 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
// node_modules/pure-web/src/js/common.js
|
|
2
|
+
function parseHTML(html) {
|
|
3
|
+
return new DOMParser().parseFromString(html, "text/html").body.childNodes;
|
|
4
|
+
}
|
|
5
|
+
function throttle(fn, timeoutMs = 100) {
|
|
6
|
+
let handle;
|
|
7
|
+
return function executedFunction(...args) {
|
|
8
|
+
const fire = () => {
|
|
9
|
+
clearTimeout(handle);
|
|
10
|
+
fn(...args);
|
|
11
|
+
};
|
|
12
|
+
clearTimeout(handle);
|
|
13
|
+
handle = setTimeout(fire, timeoutMs);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function enQueue(fn) {
|
|
17
|
+
setTimeout(fn, 0);
|
|
18
|
+
}
|
|
19
|
+
function isUrl(str) {
|
|
20
|
+
try {
|
|
21
|
+
if (typeof str !== "string")
|
|
22
|
+
return false;
|
|
23
|
+
if (str.indexOf("\n") !== -1 || str.indexOf(" ") !== -1)
|
|
24
|
+
return false;
|
|
25
|
+
if (str.startsWith("#/"))
|
|
26
|
+
return false;
|
|
27
|
+
const newUrl = new URL(str, window.location.origin);
|
|
28
|
+
return newUrl.protocol === "http:" || newUrl.protocol === "https:";
|
|
29
|
+
} catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function openCenteredWindow(url, width, height) {
|
|
34
|
+
const left = window.screen.width / 2 - width / 2;
|
|
35
|
+
const top = window.screen.height / 2 - height / 2;
|
|
36
|
+
return window.open(
|
|
37
|
+
url,
|
|
38
|
+
"",
|
|
39
|
+
`toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=${width}, height=${height}, top=${top}, left=${left}`
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// node_modules/pure-web/src/js/autocomplete.js
|
|
44
|
+
var cssClasses = {
|
|
45
|
+
result: "ac-suggestion",
|
|
46
|
+
item: "ac-itm"
|
|
47
|
+
};
|
|
48
|
+
var AutoComplete = class _AutoComplete extends EventTarget {
|
|
49
|
+
constructor(parent, textInput, settings) {
|
|
50
|
+
super();
|
|
51
|
+
this.settings = {
|
|
52
|
+
emptyResultsText: "",
|
|
53
|
+
...settings
|
|
54
|
+
};
|
|
55
|
+
this.container = parent;
|
|
56
|
+
this.input = textInput;
|
|
57
|
+
this.input.setAttribute("autocomplete", "off");
|
|
58
|
+
this.categories = settings.categories || {};
|
|
59
|
+
this.caches = /* @__PURE__ */ new Map();
|
|
60
|
+
enQueue(this.attach.bind(this));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Connector logic to call on @focus events.
|
|
64
|
+
* Lit example:
|
|
65
|
+
* <input type="search" @focus=${(e) => {AutoComplete.connect(e, this.autoComplete); }} />
|
|
66
|
+
*
|
|
67
|
+
* @param {*} event focus event
|
|
68
|
+
* @param {*} options AutoComplete options
|
|
69
|
+
*/
|
|
70
|
+
static connect(event, options) {
|
|
71
|
+
const input = event.target;
|
|
72
|
+
if (!input._autoComplete) {
|
|
73
|
+
if (!options?.categories)
|
|
74
|
+
throw Error("Missing autocomplete settings");
|
|
75
|
+
input._autoComplete = new _AutoComplete(input.parentNode, input, options);
|
|
76
|
+
if (event.type === "focus") {
|
|
77
|
+
setTimeout(() => {
|
|
78
|
+
input._autoComplete.focusHandler(event);
|
|
79
|
+
}, 100);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return input._autoComplete;
|
|
83
|
+
}
|
|
84
|
+
on(a, b) {
|
|
85
|
+
this.input.addEventListener(a, b);
|
|
86
|
+
return this;
|
|
87
|
+
}
|
|
88
|
+
attach() {
|
|
89
|
+
this.resultsDiv = document.createElement("div");
|
|
90
|
+
this.resultsDiv.title = "";
|
|
91
|
+
this.resultsDiv.classList.add(cssClasses.result);
|
|
92
|
+
if (this.container.offsetWidth > 100)
|
|
93
|
+
this.resultsDiv.style.width = this.container.offsetWidth;
|
|
94
|
+
this.resultsDiv.addEventListener("mousedown", this.resultClick.bind(this));
|
|
95
|
+
this.container.classList.add("ac-container");
|
|
96
|
+
this.input.classList.add("ac-input");
|
|
97
|
+
const inputStyle = getComputedStyle(this.input);
|
|
98
|
+
this.container.style.setProperty(
|
|
99
|
+
"--ac-bg-default",
|
|
100
|
+
inputStyle.backgroundColor
|
|
101
|
+
);
|
|
102
|
+
this.container.style.setProperty("--ac-color-default", inputStyle.color);
|
|
103
|
+
const acc = getComputedStyle(this.input).accentColor;
|
|
104
|
+
if (acc !== "auto")
|
|
105
|
+
this.container.style.setProperty("--ac-accent-color", acc);
|
|
106
|
+
(this.container?.shadowRoot ?? this.container).appendChild(this.resultsDiv);
|
|
107
|
+
this.controller().clear("attach");
|
|
108
|
+
this.on(
|
|
109
|
+
"input",
|
|
110
|
+
throttle(
|
|
111
|
+
this.inputHandler.bind(this),
|
|
112
|
+
this.settings.throttleInputMs ?? 300
|
|
113
|
+
)
|
|
114
|
+
).on("focus", this.focusHandler.bind(this)).on("focusout", this.blurHandler.bind(this)).on("keyup", this.keyUpHandler.bind(this)).on("keydown", this.keyDownHandler.bind(this));
|
|
115
|
+
}
|
|
116
|
+
controller() {
|
|
117
|
+
let c = this.internalController();
|
|
118
|
+
if (typeof this.settings.controller === "function")
|
|
119
|
+
c = this.settings.controller(this) ?? c;
|
|
120
|
+
return c;
|
|
121
|
+
}
|
|
122
|
+
internalController() {
|
|
123
|
+
return {
|
|
124
|
+
show: this.show.bind(this),
|
|
125
|
+
hide: this.hide.bind(this),
|
|
126
|
+
clear: this.clear.bind(this),
|
|
127
|
+
empty: () => {
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
moveResult(add) {
|
|
132
|
+
this.controller().show();
|
|
133
|
+
let length = this.acItems.length;
|
|
134
|
+
this.rowIndex = this.rowIndex + add;
|
|
135
|
+
if (this.rowIndex <= 0) {
|
|
136
|
+
this.rowIndex = 0;
|
|
137
|
+
} else if (this.rowIndex > length - 1) {
|
|
138
|
+
this.rowIndex = 0;
|
|
139
|
+
}
|
|
140
|
+
for (const r of this.acItems) {
|
|
141
|
+
r.classList.remove("selected");
|
|
142
|
+
}
|
|
143
|
+
let div = this.getSelectedDiv();
|
|
144
|
+
if (div) {
|
|
145
|
+
div.classList.add("selected");
|
|
146
|
+
div.scrollIntoView({
|
|
147
|
+
behavior: "smooth",
|
|
148
|
+
block: "end",
|
|
149
|
+
inline: "nearest"
|
|
150
|
+
});
|
|
151
|
+
} else {
|
|
152
|
+
this.focusHandler({
|
|
153
|
+
target: this.input
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
getSelectedDiv() {
|
|
158
|
+
return this.resultsDiv.querySelector(`div:nth-child(${this.rowIndex + 1})`);
|
|
159
|
+
}
|
|
160
|
+
// execute action
|
|
161
|
+
selectResult(div) {
|
|
162
|
+
div = div || this.getSelectedDiv();
|
|
163
|
+
if (div) {
|
|
164
|
+
let index = parseInt(div.getAttribute("data-index"));
|
|
165
|
+
this.resultClicked = true;
|
|
166
|
+
let result = this.results[index];
|
|
167
|
+
let handlingCategory = this.categories[result.category] ?? {};
|
|
168
|
+
handlingCategory.action = handlingCategory.action ?? this.setText.bind(this);
|
|
169
|
+
if (handlingCategory.newTab) {
|
|
170
|
+
this.tabWindow = openCenteredWindow("about:blank");
|
|
171
|
+
}
|
|
172
|
+
let options = {
|
|
173
|
+
...result,
|
|
174
|
+
search: this.input.value
|
|
175
|
+
};
|
|
176
|
+
div.classList.add("ac-active");
|
|
177
|
+
setTimeout(() => {
|
|
178
|
+
this.controller().hide("result-selected");
|
|
179
|
+
if (options.action) {
|
|
180
|
+
options.action(options);
|
|
181
|
+
} else {
|
|
182
|
+
handlingCategory.action(options);
|
|
183
|
+
if (handlingCategory.newTab) {
|
|
184
|
+
if (options.url) {
|
|
185
|
+
this.tabWindow.location.href = options.url;
|
|
186
|
+
} else {
|
|
187
|
+
this.tabWindow.close();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
var event = new Event("change", { bubbles: true });
|
|
192
|
+
this.input.dispatchEvent(event);
|
|
193
|
+
this.controller().clear("result-selected");
|
|
194
|
+
const ev = new Event("result-selected");
|
|
195
|
+
ev.detail = options;
|
|
196
|
+
this.input.dispatchEvent(ev);
|
|
197
|
+
}, 0);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
setText(options) {
|
|
201
|
+
let valueSet = false;
|
|
202
|
+
if (this.input) {
|
|
203
|
+
this.input.value = options.text;
|
|
204
|
+
valueSet = true;
|
|
205
|
+
} else if (this.container?.autoCompleteInput) {
|
|
206
|
+
this.container.autoCompleteInput.value = options.text;
|
|
207
|
+
valueSet = true;
|
|
208
|
+
} else if ("value" in this.container) {
|
|
209
|
+
this.container.value = options.text;
|
|
210
|
+
valueSet = true;
|
|
211
|
+
}
|
|
212
|
+
if (valueSet && this.input) {
|
|
213
|
+
this.input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
214
|
+
}
|
|
215
|
+
this.controller().hide("settext");
|
|
216
|
+
}
|
|
217
|
+
resultClick(event) {
|
|
218
|
+
this.selectResult(event.target.closest(`.${cssClasses.item}`));
|
|
219
|
+
}
|
|
220
|
+
blurHandler() {
|
|
221
|
+
setTimeout(() => {
|
|
222
|
+
if (!this.resultClicked)
|
|
223
|
+
this.controller().clear("blurred");
|
|
224
|
+
this.resultClicked = false;
|
|
225
|
+
}, 100);
|
|
226
|
+
}
|
|
227
|
+
clear() {
|
|
228
|
+
if (this.settings.debug)
|
|
229
|
+
return;
|
|
230
|
+
if (!this.resultsDiv)
|
|
231
|
+
return;
|
|
232
|
+
this.resultsDiv.innerHTML = "";
|
|
233
|
+
this.controller().hide("clear");
|
|
234
|
+
if (this.cacheTmr)
|
|
235
|
+
clearTimeout(this.cacheTmr);
|
|
236
|
+
this.cacheTmr = setTimeout(() => {
|
|
237
|
+
this.caches.clear();
|
|
238
|
+
}, 60 * 1e3 * 5);
|
|
239
|
+
}
|
|
240
|
+
show() {
|
|
241
|
+
if (!this.resultsDiv.classList.contains("ac-active")) {
|
|
242
|
+
const viewBounds = this.getViewBounds();
|
|
243
|
+
this.resultsDiv.style.position = "absolute";
|
|
244
|
+
if (viewBounds.rect.width > 100)
|
|
245
|
+
this.resultsDiv.style.width = `${viewBounds.rect.width}px`;
|
|
246
|
+
this.settings.direction = this.settings.direction ?? viewBounds.suggestedDirection;
|
|
247
|
+
this.resultsDiv.setAttribute("data-direction", this.settings.direction);
|
|
248
|
+
if (this.settings.direction === "up") {
|
|
249
|
+
this.resultsDiv.style.top = "unset";
|
|
250
|
+
this.resultsDiv.style.bottom = `${viewBounds.rect.height + 20}px`;
|
|
251
|
+
this.rowIndex = this.acItems.length;
|
|
252
|
+
} else {
|
|
253
|
+
this.resultsDiv.style.bottom = "unset";
|
|
254
|
+
this.resultsDiv.style.top = `${viewBounds.rect.height}px`;
|
|
255
|
+
this.rowIndex = -1;
|
|
256
|
+
}
|
|
257
|
+
this.resultsDiv.style.maxWidth = "unset";
|
|
258
|
+
this.resultsDiv.classList.toggle("ac-active", true);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
getViewBounds() {
|
|
262
|
+
const rect = this.input.getBoundingClientRect();
|
|
263
|
+
return {
|
|
264
|
+
rect,
|
|
265
|
+
suggestedDirection: rect.top + rect.height + 500 > window.innerHeight ? "up" : "down"
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
hide() {
|
|
269
|
+
this.resultsDiv.classList.toggle("ac-active", false);
|
|
270
|
+
}
|
|
271
|
+
empty() {
|
|
272
|
+
this.resultsDiv.innerHTML = `<div class="ac-empty">${this.settings.emptyResultsText}</div>`;
|
|
273
|
+
this.controller().show();
|
|
274
|
+
}
|
|
275
|
+
inputHandler(e) {
|
|
276
|
+
if (this.cacheTmr)
|
|
277
|
+
clearTimeout(this.cacheTmr);
|
|
278
|
+
let options = {
|
|
279
|
+
search: e.target.value,
|
|
280
|
+
categories: this.categories
|
|
281
|
+
};
|
|
282
|
+
this.container.classList.add("search-running");
|
|
283
|
+
this.getItems(options, e).then((r) => {
|
|
284
|
+
this.controller().clear("new-results");
|
|
285
|
+
this.resultsHandler(r, options);
|
|
286
|
+
this.container.classList.remove("search-running");
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
keyDownHandler(e) {
|
|
290
|
+
switch (e.key) {
|
|
291
|
+
case "Enter":
|
|
292
|
+
e.stopPropagation();
|
|
293
|
+
e.preventDefault();
|
|
294
|
+
break;
|
|
295
|
+
case "ArrowDown":
|
|
296
|
+
enQueue(this.moveResult(1));
|
|
297
|
+
break;
|
|
298
|
+
case "ArrowUp":
|
|
299
|
+
enQueue(this.moveResult(-1));
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
keyUpHandler(e) {
|
|
304
|
+
switch (e.key) {
|
|
305
|
+
case "Escape":
|
|
306
|
+
this.controller().hide("escape");
|
|
307
|
+
break;
|
|
308
|
+
case "Enter":
|
|
309
|
+
if (this.getSelectedDiv()) {
|
|
310
|
+
this.container.preventEnter = true;
|
|
311
|
+
e.stopPropagation();
|
|
312
|
+
e.preventDefault();
|
|
313
|
+
this.selectResult();
|
|
314
|
+
setTimeout(() => {
|
|
315
|
+
this.container.preventEnter = false;
|
|
316
|
+
}, 10);
|
|
317
|
+
}
|
|
318
|
+
break;
|
|
319
|
+
default:
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
focusHandler(e) {
|
|
324
|
+
this.controller().clear("focus");
|
|
325
|
+
let value = e.target.value;
|
|
326
|
+
this.suggest(value, e);
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Shows suggestion box
|
|
330
|
+
* @param {string} value - String to suggest results for
|
|
331
|
+
*/
|
|
332
|
+
suggest(value, e) {
|
|
333
|
+
this.input.focus();
|
|
334
|
+
const options = {
|
|
335
|
+
suggest: true,
|
|
336
|
+
search: value || "",
|
|
337
|
+
categories: this.categories
|
|
338
|
+
};
|
|
339
|
+
this.getItems(options, e).then((r) => {
|
|
340
|
+
this.input.dispatchEvent(
|
|
341
|
+
new CustomEvent("show-results", {
|
|
342
|
+
detail: {
|
|
343
|
+
results: r
|
|
344
|
+
}
|
|
345
|
+
})
|
|
346
|
+
);
|
|
347
|
+
this.resultsHandler(r, options);
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
// Sort results based on static (integer) or dynamic (function) sortIndex in category.
|
|
351
|
+
sort(r, options) {
|
|
352
|
+
return r.sort((a, b) => {
|
|
353
|
+
const aCat = options.categories[a.category];
|
|
354
|
+
const bCat = options.categories[b.category];
|
|
355
|
+
const aIndex = typeof aCat.sortIndex === "function" ? aCat.sortIndex(options) : aCat.sortIndex ?? 0;
|
|
356
|
+
const bIndex = typeof bCat.sortIndex === "function" ? bCat.sortIndex(options) : bCat.sortIndex ?? 0;
|
|
357
|
+
return bIndex > aIndex ? 1 : -1;
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
resultsHandler(r, options) {
|
|
361
|
+
this.results = r;
|
|
362
|
+
this.rowIndex = -1;
|
|
363
|
+
let index = 0;
|
|
364
|
+
const singleItemTemplate = (catHandler, i) => {
|
|
365
|
+
return (
|
|
366
|
+
/*html*/
|
|
367
|
+
`
|
|
368
|
+
<div title="${i.tooltip || ""}" data-index="${index}" class="${`${cssClasses.item} cat-${i.category} ${i.class ?? ""}`.trim()}"${i.style ? ` style="${i.style}"` : ""}>
|
|
369
|
+
${this.handleImageOrIcon(i)}
|
|
370
|
+
<span class="text">${this.formatResultItem(
|
|
371
|
+
i,
|
|
372
|
+
options,
|
|
373
|
+
catHandler
|
|
374
|
+
)}</span>
|
|
375
|
+
${!this.settings.hideCategory ? `<span class="category">${i.category || ""}</span>` : ""}
|
|
376
|
+
</div>`
|
|
377
|
+
);
|
|
378
|
+
};
|
|
379
|
+
r.forEach((i) => {
|
|
380
|
+
let catHandler = options.categories[i.category] || {};
|
|
381
|
+
if (i.element) {
|
|
382
|
+
this.resultsDiv.appendChild(i.element);
|
|
383
|
+
} else {
|
|
384
|
+
i = typeof i === "string" ? { text: i } : i;
|
|
385
|
+
this.resultsDiv.appendChild(
|
|
386
|
+
parseHTML(singleItemTemplate(catHandler, i))[0]
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
index++;
|
|
390
|
+
});
|
|
391
|
+
if (r.length) {
|
|
392
|
+
this.acItems = this.resultsDiv.querySelectorAll(".ac-itm");
|
|
393
|
+
this.controller().show();
|
|
394
|
+
} else if (options.search.length)
|
|
395
|
+
this.controller().empty();
|
|
396
|
+
}
|
|
397
|
+
handleImageOrIcon(i) {
|
|
398
|
+
if (i.image) {
|
|
399
|
+
return (
|
|
400
|
+
/*html*/
|
|
401
|
+
`<img src="${i.image}"/>`
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
if (typeof this.settings.iconHandler === "function")
|
|
405
|
+
return this.settings.iconHandler(i);
|
|
406
|
+
return (
|
|
407
|
+
/*html*/
|
|
408
|
+
`<svg-icon icon="${i.icon}"></svg-icon>`
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
formatResultItem(item, options, catHandler) {
|
|
412
|
+
const i = typeof item === "string" ? { text: item } : item;
|
|
413
|
+
let result = i.text;
|
|
414
|
+
if (options.search) {
|
|
415
|
+
result = result.replace("%search%", options.search);
|
|
416
|
+
i.description = i.description?.replace("%search%", options.search);
|
|
417
|
+
}
|
|
418
|
+
result = this.highlight(result, options.search);
|
|
419
|
+
if (i.description) {
|
|
420
|
+
result = `<div>${result}</div><small>${i.description}</small>`;
|
|
421
|
+
}
|
|
422
|
+
if (catHandler.format) {
|
|
423
|
+
result = catHandler.format({
|
|
424
|
+
item: i,
|
|
425
|
+
result,
|
|
426
|
+
options
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
return result;
|
|
430
|
+
}
|
|
431
|
+
highlight(str, find) {
|
|
432
|
+
var reg = new RegExp("(" + find + ")", "gi");
|
|
433
|
+
return str.replace(reg, '<span class="txt-hl">$1</span>');
|
|
434
|
+
}
|
|
435
|
+
async getItems(options, e) {
|
|
436
|
+
if (this.aborter) {
|
|
437
|
+
this.aborter.abort();
|
|
438
|
+
}
|
|
439
|
+
let cache = this.caches.get(options.search);
|
|
440
|
+
if (cache)
|
|
441
|
+
return cache;
|
|
442
|
+
const prop = this.settings.map;
|
|
443
|
+
const normalizeItem = (i) => {
|
|
444
|
+
if (typeof i === "string")
|
|
445
|
+
i = { text: i };
|
|
446
|
+
return i;
|
|
447
|
+
};
|
|
448
|
+
const map = (list) => {
|
|
449
|
+
if (!prop) {
|
|
450
|
+
return list.map((i) => {
|
|
451
|
+
return normalizeItem(i);
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
return list.map((i) => {
|
|
455
|
+
return { text: i[prop] };
|
|
456
|
+
});
|
|
457
|
+
};
|
|
458
|
+
const max = (list) => {
|
|
459
|
+
if (this.settings.max && this.settings.max > 0) {
|
|
460
|
+
list.length = this.settings.max;
|
|
461
|
+
}
|
|
462
|
+
return list;
|
|
463
|
+
};
|
|
464
|
+
this.aborter = new AbortController();
|
|
465
|
+
this.aborterSignal = this.aborter.signal;
|
|
466
|
+
return new Promise((resolve) => {
|
|
467
|
+
const internalResolve = (data) => {
|
|
468
|
+
data = this.sort(data, options);
|
|
469
|
+
if (this.settings.cache !== false)
|
|
470
|
+
this.caches.set(options.search, data);
|
|
471
|
+
resolve(data);
|
|
472
|
+
};
|
|
473
|
+
if (isUrl(this.items)) {
|
|
474
|
+
if (this.settings.minlength > 0) {
|
|
475
|
+
if (!options.search || options.search.length < this.settings.minlength) {
|
|
476
|
+
internalResolve([]);
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
let url = this.formatSearch(this.items, options);
|
|
481
|
+
fetch(url).then((x) => {
|
|
482
|
+
if (x.status === 200) {
|
|
483
|
+
x.json().then((items) => {
|
|
484
|
+
items = map(items);
|
|
485
|
+
internalResolve(
|
|
486
|
+
max(
|
|
487
|
+
items.filter((i) => {
|
|
488
|
+
return this.isMatch(options, i);
|
|
489
|
+
})
|
|
490
|
+
)
|
|
491
|
+
);
|
|
492
|
+
});
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
throw Error(`HTTP error ${x.status} - ${url}`);
|
|
496
|
+
});
|
|
497
|
+
} else if (Array.isArray(this.items)) {
|
|
498
|
+
let simple = true;
|
|
499
|
+
this.items = this.items.map((i) => {
|
|
500
|
+
if (typeof i === "string") {
|
|
501
|
+
return { text: i };
|
|
502
|
+
}
|
|
503
|
+
simple = false;
|
|
504
|
+
return i;
|
|
505
|
+
});
|
|
506
|
+
if (simple) {
|
|
507
|
+
this.container.classList.add("simple");
|
|
508
|
+
}
|
|
509
|
+
internalResolve(max(map(this.items)));
|
|
510
|
+
} else if (typeof this.items === "function") {
|
|
511
|
+
options.control = this.container;
|
|
512
|
+
let ar = Promise.resolve(this.items(options, e));
|
|
513
|
+
ar.then((ar2) => {
|
|
514
|
+
ar2 = ar2.map((i) => {
|
|
515
|
+
return normalizeItem(i);
|
|
516
|
+
});
|
|
517
|
+
ar2 = map(ar2);
|
|
518
|
+
internalResolve(ar2);
|
|
519
|
+
});
|
|
520
|
+
} else {
|
|
521
|
+
return internalResolve(
|
|
522
|
+
Promise.resolve(this.items.apply(this, options))
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
async items(options) {
|
|
528
|
+
let arr = [];
|
|
529
|
+
options.results = [];
|
|
530
|
+
options.signal = this.aborterSignal;
|
|
531
|
+
for (var c in options.categories) {
|
|
532
|
+
let catHandler = options.categories[c];
|
|
533
|
+
catHandler.trigger = catHandler.trigger ?? (() => {
|
|
534
|
+
return true;
|
|
535
|
+
});
|
|
536
|
+
options.results = arr;
|
|
537
|
+
if (catHandler.trigger(options)) {
|
|
538
|
+
let catResults = [];
|
|
539
|
+
try {
|
|
540
|
+
catResults = await catHandler.getItems(options);
|
|
541
|
+
} catch (ex) {
|
|
542
|
+
console.warn(`Error loading items for omniBox category '${c}'.`, ex);
|
|
543
|
+
}
|
|
544
|
+
arr = arr.concat(
|
|
545
|
+
catResults.map((i) => {
|
|
546
|
+
i.category = c;
|
|
547
|
+
return i;
|
|
548
|
+
})
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return arr;
|
|
553
|
+
}
|
|
554
|
+
formatSearch(url, options) {
|
|
555
|
+
if (url.indexOf("%search%")) {
|
|
556
|
+
return url.replace("%search%", options.search || "");
|
|
557
|
+
}
|
|
558
|
+
return url + "?" + this.createQueryParam(options);
|
|
559
|
+
}
|
|
560
|
+
createQueryParam(options) {
|
|
561
|
+
let suggest = options.suggest ? "&suggest=true" : "";
|
|
562
|
+
return `q=${options.text}${suggest}`;
|
|
563
|
+
}
|
|
564
|
+
isMatch(options, i) {
|
|
565
|
+
if (i.text?.indexOf("%search%") >= 0)
|
|
566
|
+
return true;
|
|
567
|
+
return options.search ? i.text?.toLowerCase().indexOf(options.search.toLowerCase()) >= 0 : options.suggest;
|
|
568
|
+
}
|
|
569
|
+
static textFilter(options, propertyName) {
|
|
570
|
+
return function(i) {
|
|
571
|
+
if (!options.search)
|
|
572
|
+
return true;
|
|
573
|
+
if (i.hidden)
|
|
574
|
+
return false;
|
|
575
|
+
const prop = propertyName ? i[propertyName] : i;
|
|
576
|
+
const isMatch = prop.match(new RegExp(options.search, "gi"));
|
|
577
|
+
if (isMatch)
|
|
578
|
+
return isMatch;
|
|
579
|
+
if (i.config?.tags) {
|
|
580
|
+
return i.config.tags.some((tag) => {
|
|
581
|
+
return tag.match(new RegExp(options.search, "gi"));
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
// src/js/pds-autocomplete.js
|
|
589
|
+
var originalSelectResult = AutoComplete?.prototype?.selectResult;
|
|
590
|
+
if (typeof originalSelectResult === "function" && AutoComplete?.prototype?.__pdsSelectedItemPatched !== true) {
|
|
591
|
+
AutoComplete.prototype.selectResult = function patchedSelectResult(div) {
|
|
592
|
+
const selectedItem = div || this.getSelectedDiv?.();
|
|
593
|
+
if (!selectedItem) {
|
|
594
|
+
return originalSelectResult.call(this, div);
|
|
595
|
+
}
|
|
596
|
+
const indexRaw = selectedItem.getAttribute?.("data-index") ?? "";
|
|
597
|
+
const index = Number.parseInt(indexRaw, 10);
|
|
598
|
+
const result = Number.isInteger(index) ? this.results?.[index] : null;
|
|
599
|
+
const categoryConfig = result && this.categories ? this.categories[result.category] : null;
|
|
600
|
+
const restores = [];
|
|
601
|
+
const wrapAction = (target, key) => {
|
|
602
|
+
if (!target || typeof target[key] !== "function")
|
|
603
|
+
return;
|
|
604
|
+
const originalAction = target[key];
|
|
605
|
+
let restored = false;
|
|
606
|
+
const restore = () => {
|
|
607
|
+
if (restored)
|
|
608
|
+
return;
|
|
609
|
+
target[key] = originalAction;
|
|
610
|
+
restored = true;
|
|
611
|
+
};
|
|
612
|
+
target[key] = function wrappedAction(options = {}, ...rest) {
|
|
613
|
+
try {
|
|
614
|
+
if (options && typeof options === "object" && !("selectedItem" in options)) {
|
|
615
|
+
options.selectedItem = selectedItem;
|
|
616
|
+
}
|
|
617
|
+
return originalAction.call(this, options, ...rest);
|
|
618
|
+
} finally {
|
|
619
|
+
restore();
|
|
620
|
+
}
|
|
621
|
+
};
|
|
622
|
+
restores.push(restore);
|
|
623
|
+
};
|
|
624
|
+
wrapAction(result, "action");
|
|
625
|
+
wrapAction(categoryConfig, "action");
|
|
626
|
+
const output = originalSelectResult.call(this, selectedItem);
|
|
627
|
+
setTimeout(() => {
|
|
628
|
+
for (const restore of restores) {
|
|
629
|
+
restore();
|
|
630
|
+
}
|
|
631
|
+
}, 1e3);
|
|
632
|
+
return output;
|
|
633
|
+
};
|
|
634
|
+
AutoComplete.prototype.__pdsSelectedItemPatched = true;
|
|
635
|
+
}
|
|
636
|
+
export {
|
|
637
|
+
AutoComplete
|
|
638
|
+
};
|
|
639
|
+
//# sourceMappingURL=pds-autocomplete.js.map
|