@optionfactory/ful 6.0.8 → 7.0.1
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/ful-client-errors.iife.js +40 -11
- package/dist/ful-client-errors.iife.js.map +1 -1
- package/dist/ful-client-errors.iife.min.js +1 -1
- package/dist/ful-client-errors.iife.min.js.map +1 -1
- package/dist/ful.d.mts +941 -0
- package/dist/ful.iife.js +79 -33
- package/dist/ful.iife.js.map +1 -1
- package/dist/ful.iife.min.js +1 -1
- package/dist/ful.iife.min.js.map +1 -1
- package/dist/ful.min.mjs +1 -1
- package/dist/ful.min.mjs.map +1 -1
- package/dist/ful.mjs +79 -33
- package/dist/ful.mjs.map +1 -1
- package/package.json +19 -12
package/dist/ful.iife.js
CHANGED
|
@@ -978,59 +978,108 @@ var ful = (function (exports, ftl) {
|
|
|
978
978
|
}
|
|
979
979
|
}
|
|
980
980
|
|
|
981
|
+
/**
|
|
982
|
+
* @typedef {Object} AsyncExtension
|
|
983
|
+
* @property {Promise<any>[]} promises
|
|
984
|
+
* @typedef {Event & { async?: AsyncExtension }} AsyncEvent
|
|
985
|
+
*/
|
|
981
986
|
class AsyncEvents {
|
|
982
|
-
|
|
987
|
+
/**
|
|
988
|
+
* Dispatches an event and handles asynchronous resolution based on the execution mode.
|
|
989
|
+
* @param {HTMLElement} el - The target element dispatching the event.
|
|
990
|
+
* @param {AsyncEvent} evt - The event instance.
|
|
991
|
+
* @param {{mode?: 'broadcast' | 'pipeline' | 'delegate'}} [options] - Configuration options (defaults to 'broadcast').
|
|
992
|
+
* @returns {Promise<any>} Resolves with an array of values for broadcasts, a single value for pipelines/delegates, or undefined.
|
|
993
|
+
*/
|
|
994
|
+
static async fireAsync(el, evt, options) {
|
|
983
995
|
el.dispatchEvent(evt);
|
|
984
|
-
|
|
996
|
+
const promises = evt.async?.promises ?? [];
|
|
997
|
+
const mode = options?.mode ?? 'broadcast';
|
|
998
|
+
if (mode === 'pipeline' && promises.length > 1) {
|
|
999
|
+
throw new Error(`[AsyncEvents] Event "${evt.type}" is configured in 'pipeline' mode and expects at most one async listener, but ${promises.length} listeners were triggered on this element.`);
|
|
1000
|
+
}
|
|
1001
|
+
if (mode === 'delegate' && promises.length !== 1) {
|
|
1002
|
+
throw new Error(`[AsyncEvents] Event "${evt.type}" is configured in 'delegate' mode and requires exactly one async listener, but ${promises.length} were registered.`);
|
|
1003
|
+
}
|
|
1004
|
+
return mode === 'broadcast' ? Promise.all(promises) : Promise.resolve(promises[0]);
|
|
985
1005
|
}
|
|
1006
|
+
|
|
986
1007
|
/**
|
|
987
|
-
*
|
|
988
|
-
* @param {
|
|
989
|
-
* @param {
|
|
990
|
-
* @param {
|
|
991
|
-
* @param {
|
|
992
|
-
* @returns
|
|
1008
|
+
* Registers an asynchronous event listener wrapper.
|
|
1009
|
+
* @param {HTMLElement} el - The target element.
|
|
1010
|
+
* @param {string} type - The event name/type.
|
|
1011
|
+
* @param {Function} fn - The async listener middleware function returning the execution result.
|
|
1012
|
+
* @param {AddEventListenerOptions} [options] - Native addEventListener options.
|
|
1013
|
+
* @returns {EventListener} The underlying proxy listener function needed for cleanup via asyncOff.
|
|
993
1014
|
*/
|
|
994
1015
|
static asyncOn(el, type, fn, options) {
|
|
1016
|
+
/** @type {(evt: Event) => Promise<void>} */
|
|
995
1017
|
const listener = async (event) => {
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
});
|
|
1001
|
-
|
|
1018
|
+
const ae = /** @type {AsyncEvent} */ (event);
|
|
1019
|
+
if (!ae.async) {
|
|
1020
|
+
ae.async = { promises: [] };
|
|
1021
|
+
}
|
|
1022
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
1023
|
+
ae.async.promises.push(promise);
|
|
1002
1024
|
try {
|
|
1003
|
-
|
|
1004
|
-
resolve(await fn(event));
|
|
1025
|
+
resolve(await fn(ae));
|
|
1005
1026
|
} catch (e) {
|
|
1006
|
-
//@ts-ignore
|
|
1007
1027
|
reject(e);
|
|
1008
1028
|
}
|
|
1009
1029
|
};
|
|
1030
|
+
|
|
1010
1031
|
el.addEventListener(type, listener, options);
|
|
1011
1032
|
return listener;
|
|
1012
1033
|
}
|
|
1034
|
+
|
|
1013
1035
|
/**
|
|
1014
|
-
*
|
|
1015
|
-
* @param {
|
|
1016
|
-
* @param {
|
|
1017
|
-
* @param {
|
|
1018
|
-
* @param {
|
|
1019
|
-
*/
|
|
1036
|
+
* Unregisters an asynchronous event listener proxy.
|
|
1037
|
+
* @param {HTMLElement} el - The target element.
|
|
1038
|
+
* @param {string} type - The event name/type.
|
|
1039
|
+
* @param {EventListener} listener - The proxy listener instance previously returned by asyncOn.
|
|
1040
|
+
* @param {EventListenerOptions} [options] - Native removeEventListener options.
|
|
1041
|
+
*/
|
|
1020
1042
|
static asyncOff(el, type, listener, options) {
|
|
1021
1043
|
el.removeEventListener(type, listener, options);
|
|
1022
1044
|
}
|
|
1045
|
+
|
|
1046
|
+
/**
|
|
1047
|
+
* Mixes the asynchronous execution engine extensions into target class prototypes.
|
|
1048
|
+
* @param {...Function} classes - The target class constructors to decorate.
|
|
1049
|
+
*/
|
|
1023
1050
|
static mixInto(...classes) {
|
|
1024
1051
|
for (const k of classes) {
|
|
1025
1052
|
Object.assign(k.prototype, {
|
|
1026
|
-
|
|
1027
|
-
|
|
1053
|
+
/**
|
|
1054
|
+
* @this {HTMLElement}
|
|
1055
|
+
* @param {AsyncEvent} evt
|
|
1056
|
+
* @param {{mode?: 'broadcast' | 'pipeline' | 'delegate'}} [options]
|
|
1057
|
+
* @returns {Promise<any>}
|
|
1058
|
+
*/
|
|
1059
|
+
async fireAsync(evt, options) {
|
|
1060
|
+
return await AsyncEvents.fireAsync(this, evt, options);
|
|
1028
1061
|
},
|
|
1062
|
+
|
|
1063
|
+
/**
|
|
1064
|
+
* @this {HTMLElement}
|
|
1065
|
+
* @param {string} type
|
|
1066
|
+
* @param {Function} fn
|
|
1067
|
+
* @param {AddEventListenerOptions} [options]
|
|
1068
|
+
* @returns {EventListener}
|
|
1069
|
+
*/
|
|
1029
1070
|
asyncOn(type, fn, options) {
|
|
1030
1071
|
return AsyncEvents.asyncOn(this, type, fn, options);
|
|
1031
1072
|
},
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* @this {HTMLElement}
|
|
1076
|
+
* @param {string} type
|
|
1077
|
+
* @param {EventListener} listener
|
|
1078
|
+
* @param {EventListenerOptions} [options]
|
|
1079
|
+
* @returns {void}
|
|
1080
|
+
*/
|
|
1032
1081
|
asyncOff(type, listener, options) {
|
|
1033
|
-
|
|
1082
|
+
AsyncEvents.asyncOff(this, type, listener, options);
|
|
1034
1083
|
}
|
|
1035
1084
|
});
|
|
1036
1085
|
}
|
|
@@ -1384,7 +1433,7 @@ var ful = (function (exports, ftl) {
|
|
|
1384
1433
|
}
|
|
1385
1434
|
this.errors = [];
|
|
1386
1435
|
const sre = new CustomEvent('submit:requested', { bubbles: true, cancelable: false, detail: { submitter, values: se.detail.values, request: se.detail.request} });
|
|
1387
|
-
let response = await AsyncEvents.fireAsync(this, sre);
|
|
1436
|
+
let response = await AsyncEvents.fireAsync(this, sre, {mode: "pipeline"});
|
|
1388
1437
|
request = sre.detail.request;
|
|
1389
1438
|
|
|
1390
1439
|
response = await loader.submit(request, this, response);
|
|
@@ -1533,7 +1582,6 @@ var ful = (function (exports, ftl) {
|
|
|
1533
1582
|
ftl.Attributes.toggle(this, 'readonly', v);
|
|
1534
1583
|
});
|
|
1535
1584
|
}
|
|
1536
|
-
//@ts-ignore
|
|
1537
1585
|
get disabled() {
|
|
1538
1586
|
return this._input.hasAttribute('disabled');
|
|
1539
1587
|
}
|
|
@@ -2158,11 +2206,12 @@ var ful = (function (exports, ftl) {
|
|
|
2158
2206
|
this.#menu = fragment.querySelector("menu");
|
|
2159
2207
|
this.#menu.addEventListener('click', evt => {
|
|
2160
2208
|
evt.stopPropagation();
|
|
2161
|
-
|
|
2209
|
+
const li = evt.target.closest('li');
|
|
2210
|
+
if (!li) {
|
|
2162
2211
|
this.hide();
|
|
2163
2212
|
return;
|
|
2164
2213
|
}
|
|
2165
|
-
this.#change(
|
|
2214
|
+
this.#change(li);
|
|
2166
2215
|
});
|
|
2167
2216
|
this.replaceChildren(fragment);
|
|
2168
2217
|
}
|
|
@@ -2461,7 +2510,6 @@ var ful = (function (exports, ftl) {
|
|
|
2461
2510
|
}
|
|
2462
2511
|
return [...this.#values.entries()][0] ?? null;
|
|
2463
2512
|
}
|
|
2464
|
-
//@ts-ignore
|
|
2465
2513
|
get disabled() {
|
|
2466
2514
|
return this.#input.hasAttribute('disabled');
|
|
2467
2515
|
}
|
|
@@ -2609,7 +2657,6 @@ var ful = (function (exports, ftl) {
|
|
|
2609
2657
|
ftl.Attributes.toggle(this, 'readonly', v);
|
|
2610
2658
|
});
|
|
2611
2659
|
}
|
|
2612
|
-
//@ts-ignore
|
|
2613
2660
|
get disabled(){
|
|
2614
2661
|
return this.#fieldset.hasAttribute('disabled');
|
|
2615
2662
|
}
|
|
@@ -2719,7 +2766,6 @@ var ful = (function (exports, ftl) {
|
|
|
2719
2766
|
ftl.Attributes.toggle(this, 'readonly', v);
|
|
2720
2767
|
});
|
|
2721
2768
|
}
|
|
2722
|
-
//@ts-ignore
|
|
2723
2769
|
get disabled() {
|
|
2724
2770
|
return this.#input.hasAttribute('disabled');
|
|
2725
2771
|
}
|