Skip to content

Commit 93b1f34

Browse files
committed
[Autocomplete] Ensure default plugins are nicely merged with user-defined plugins
1 parent 7292e1a commit 93b1f34

File tree

2 files changed

+64
-14
lines changed

2 files changed

+64
-14
lines changed

src/Autocomplete/assets/dist/controller.js

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,28 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
2929
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
3030
};
3131

32-
var _default_1_instances, _default_1_getCommonConfig, _default_1_createAutocomplete, _default_1_createAutocompleteWithHtmlContents, _default_1_createAutocompleteWithRemoteData, _default_1_stripTags, _default_1_mergeObjects, _default_1_createTomSelect;
32+
var _default_1_instances, _default_1_getCommonConfig, _default_1_createAutocomplete, _default_1_createAutocompleteWithHtmlContents, _default_1_createAutocompleteWithRemoteData, _default_1_stripTags, _default_1_mergeConfigs, _default_1_normalizePluginsToHash, _default_1_createTomSelect;
3333
class default_1 extends Controller {
3434
constructor() {
3535
super(...arguments);
3636
_default_1_instances.add(this);
3737
this.isObserving = false;
3838
this.hasLoadedChoicesPreviously = false;
3939
this.originalOptions = [];
40+
_default_1_normalizePluginsToHash.set(this, (plugins) => {
41+
if (Array.isArray(plugins)) {
42+
return plugins.reduce((acc, plugin) => {
43+
if (typeof plugin === 'string') {
44+
acc[plugin] = {};
45+
}
46+
if (typeof plugin === 'object' && plugin.name) {
47+
acc[plugin.name] = plugin.options || {};
48+
}
49+
return acc;
50+
}, {});
51+
}
52+
return plugins;
53+
});
4054
}
4155
initialize() {
4256
if (!this.mutationObserver) {
@@ -223,7 +237,7 @@ class default_1 extends Controller {
223237
[...originalOptionsSet].every((option) => newOptionsSet.has(option)));
224238
}
225239
}
226-
_default_1_instances = new WeakSet(), _default_1_getCommonConfig = function _default_1_getCommonConfig() {
240+
_default_1_normalizePluginsToHash = new WeakMap(), _default_1_instances = new WeakSet(), _default_1_getCommonConfig = function _default_1_getCommonConfig() {
227241
const plugins = {};
228242
const isMultiple = !this.selectElement || this.selectElement.multiple;
229243
if (!this.formElement.disabled && !isMultiple) {
@@ -288,16 +302,16 @@ _default_1_instances = new WeakSet(), _default_1_getCommonConfig = function _def
288302
if (!this.selectElement && !this.urlValue) {
289303
config.shouldLoad = () => false;
290304
}
291-
return __classPrivateFieldGet(this, _default_1_instances, "m", _default_1_mergeObjects).call(this, config, this.tomSelectOptionsValue);
305+
return __classPrivateFieldGet(this, _default_1_instances, "m", _default_1_mergeConfigs).call(this, config, this.tomSelectOptionsValue);
292306
}, _default_1_createAutocomplete = function _default_1_createAutocomplete() {
293-
const config = __classPrivateFieldGet(this, _default_1_instances, "m", _default_1_mergeObjects).call(this, __classPrivateFieldGet(this, _default_1_instances, "m", _default_1_getCommonConfig).call(this), {
307+
const config = __classPrivateFieldGet(this, _default_1_instances, "m", _default_1_mergeConfigs).call(this, __classPrivateFieldGet(this, _default_1_instances, "m", _default_1_getCommonConfig).call(this), {
294308
maxOptions: this.getMaxOptions(),
295309
});
296310
return __classPrivateFieldGet(this, _default_1_instances, "m", _default_1_createTomSelect).call(this, config);
297311
}, _default_1_createAutocompleteWithHtmlContents = function _default_1_createAutocompleteWithHtmlContents() {
298312
const commonConfig = __classPrivateFieldGet(this, _default_1_instances, "m", _default_1_getCommonConfig).call(this);
299313
const labelField = commonConfig.labelField ?? 'text';
300-
const config = __classPrivateFieldGet(this, _default_1_instances, "m", _default_1_mergeObjects).call(this, commonConfig, {
314+
const config = __classPrivateFieldGet(this, _default_1_instances, "m", _default_1_mergeConfigs).call(this, commonConfig, {
301315
maxOptions: this.getMaxOptions(),
302316
score: (search) => {
303317
const scoringFunction = this.tomSelect.getScoreFunction(search);
@@ -314,7 +328,7 @@ _default_1_instances = new WeakSet(), _default_1_getCommonConfig = function _def
314328
}, _default_1_createAutocompleteWithRemoteData = function _default_1_createAutocompleteWithRemoteData(autocompleteEndpointUrl, minCharacterLength) {
315329
const commonConfig = __classPrivateFieldGet(this, _default_1_instances, "m", _default_1_getCommonConfig).call(this);
316330
const labelField = commonConfig.labelField ?? 'text';
317-
const config = __classPrivateFieldGet(this, _default_1_instances, "m", _default_1_mergeObjects).call(this, commonConfig, {
331+
const config = __classPrivateFieldGet(this, _default_1_instances, "m", _default_1_mergeConfigs).call(this, commonConfig, {
318332
firstUrl: (query) => {
319333
const separator = autocompleteEndpointUrl.includes('?') ? '&' : '?';
320334
return `${autocompleteEndpointUrl}${separator}query=${encodeURIComponent(query)}`;
@@ -364,8 +378,15 @@ _default_1_instances = new WeakSet(), _default_1_getCommonConfig = function _def
364378
return __classPrivateFieldGet(this, _default_1_instances, "m", _default_1_createTomSelect).call(this, config);
365379
}, _default_1_stripTags = function _default_1_stripTags(string) {
366380
return string.replace(/(<([^>]+)>)/gi, '');
367-
}, _default_1_mergeObjects = function _default_1_mergeObjects(object1, object2) {
368-
return { ...object1, ...object2 };
381+
}, _default_1_mergeConfigs = function _default_1_mergeConfigs(config1, config2) {
382+
return {
383+
...config1,
384+
...config2,
385+
plugins: {
386+
...__classPrivateFieldGet(this, _default_1_normalizePluginsToHash, "f").call(this, config1.plugins || {}),
387+
...__classPrivateFieldGet(this, _default_1_normalizePluginsToHash, "f").call(this, config2.plugins || {}),
388+
},
389+
};
369390
}, _default_1_createTomSelect = function _default_1_createTomSelect(options) {
370391
const preConnectPayload = { options };
371392
this.dispatchEvent('pre-connect', preConnectPayload);

src/Autocomplete/assets/src/controller.ts

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -214,11 +214,11 @@ export default class extends Controller {
214214
config.shouldLoad = () => false;
215215
}
216216

217-
return this.#mergeObjects(config, this.tomSelectOptionsValue);
217+
return this.#mergeConfigs(config, this.tomSelectOptionsValue);
218218
}
219219

220220
#createAutocomplete(): TomSelect {
221-
const config = this.#mergeObjects(this.#getCommonConfig(), {
221+
const config = this.#mergeConfigs(this.#getCommonConfig(), {
222222
maxOptions: this.getMaxOptions(),
223223
});
224224

@@ -229,7 +229,7 @@ export default class extends Controller {
229229
const commonConfig = this.#getCommonConfig();
230230
const labelField = commonConfig.labelField ?? 'text';
231231

232-
const config = this.#mergeObjects(commonConfig, {
232+
const config = this.#mergeConfigs(commonConfig, {
233233
maxOptions: this.getMaxOptions(),
234234
score: (search: string) => {
235235
const scoringFunction = this.tomSelect.getScoreFunction(search);
@@ -251,7 +251,7 @@ export default class extends Controller {
251251
const commonConfig = this.#getCommonConfig();
252252
const labelField = commonConfig.labelField ?? 'text';
253253

254-
const config: RecursivePartial<TomSettings> = this.#mergeObjects(commonConfig, {
254+
const config: RecursivePartial<TomSettings> = this.#mergeConfigs(commonConfig, {
255255
firstUrl: (query: string) => {
256256
const separator = autocompleteEndpointUrl.includes('?') ? '&' : '?';
257257

@@ -325,10 +325,39 @@ export default class extends Controller {
325325
return string.replace(/(<([^>]+)>)/gi, '');
326326
}
327327

328-
#mergeObjects(object1: any, object2: any): any {
329-
return { ...object1, ...object2 };
328+
#mergeConfigs(config1: any, config2: any): any {
329+
return {
330+
...config1,
331+
...config2,
332+
// Plugins from both configs should be merged together.
333+
plugins: {
334+
...this.#normalizePluginsToHash(config1.plugins || {}),
335+
...this.#normalizePluginsToHash(config2.plugins || {}),
336+
},
337+
};
330338
}
331339

340+
/**
341+
* Normalizes the plugins to a hash, so that we can merge them easily.
342+
*/
343+
#normalizePluginsToHash = (plugins: TomSettings['plugins']): TPluginHash => {
344+
if (Array.isArray(plugins)) {
345+
return plugins.reduce((acc, plugin) => {
346+
if (typeof plugin === 'string') {
347+
acc[plugin] = {};
348+
}
349+
350+
if (typeof plugin === 'object' && plugin.name) {
351+
acc[plugin.name] = plugin.options || {};
352+
}
353+
354+
return acc;
355+
}, {} as TPluginHash);
356+
}
357+
358+
return plugins;
359+
};
360+
332361
/**
333362
* Returns the element, but only if it's a select element.
334363
*/

0 commit comments

Comments
 (0)