@optionfactory/fml 8.0.2 → 8.0.3
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/custom-elements.json +11 -11
- package/dist/fml.css +1 -1
- package/dist/fml.css.map +1 -1
- package/dist/fml.d.mts +36 -13
- package/dist/fml.iife.js +104 -61
- package/dist/fml.iife.js.map +1 -1
- package/dist/fml.iife.min.js +1 -1
- package/dist/fml.iife.min.js.map +1 -1
- package/dist/fml.min.mjs +1 -1
- package/dist/fml.min.mjs.map +1 -1
- package/dist/fml.mjs +104 -61
- package/dist/fml.mjs.map +1 -1
- package/dist/ftl.d.mts +24 -1
- package/dist/ftl.iife.js +27 -26
- package/dist/ftl.iife.js.map +1 -1
- package/dist/ftl.iife.min.js +1 -1
- package/dist/ftl.iife.min.js.map +1 -1
- package/dist/ftl.min.mjs +1 -1
- package/dist/ftl.min.mjs.map +1 -1
- package/dist/ftl.mjs +27 -26
- package/dist/ftl.mjs.map +1 -1
- package/dist/ful.d.mts +12 -12
- package/dist/ful.iife.js +77 -35
- 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 +77 -35
- package/dist/ful.mjs.map +1 -1
- package/dist/vscode.html-custom-data.json +11 -11
- package/dist/web-types.json +12 -12
- package/package.json +1 -1
package/dist/ful.mjs
CHANGED
|
@@ -778,15 +778,17 @@ class Input extends ParsedElement {
|
|
|
778
778
|
});
|
|
779
779
|
}
|
|
780
780
|
get disabled() {
|
|
781
|
-
|
|
781
|
+
//the claim only, like a native input: the effective state, claim or disabled
|
|
782
|
+
//ancestry, is what :disabled matches
|
|
783
|
+
return this.hasAttribute('disabled');
|
|
782
784
|
}
|
|
783
785
|
set disabled(d) {
|
|
784
|
-
|
|
785
|
-
//also on the host: a form associated element only matches :disabled through its
|
|
786
|
-
//own attribute, and that is what keeps it out of the submitted values. no reflect
|
|
787
|
-
//is needed, disabled is deliberately not observed: the platform delivers it
|
|
788
|
-
//through formDisabledCallback, which also covers a disabled ancestor fieldset
|
|
786
|
+
//the claim belongs to the author alone, nothing else ever writes it
|
|
789
787
|
Attributes.toggle(this, 'disabled', d);
|
|
788
|
+
//the inner control carries the claim as a native input would: a disabled
|
|
789
|
+
//fieldset ancestry is left to the browser, which reaches the inner control
|
|
790
|
+
//as a descendant of the fieldset and re-enables it on its own
|
|
791
|
+
Attributes.toggle(this._input, 'disabled', d);
|
|
790
792
|
}
|
|
791
793
|
get required() {
|
|
792
794
|
return this._input.getAttribute('aria-required') === 'true';
|
|
@@ -1706,7 +1708,9 @@ class Select extends ParsedElement {
|
|
|
1706
1708
|
if (e.target.matches('input')) {
|
|
1707
1709
|
return;
|
|
1708
1710
|
}
|
|
1709
|
-
|
|
1711
|
+
//badges and other chrome are not form controls, the guard must ask the
|
|
1712
|
+
//effective state
|
|
1713
|
+
if (this.matches(':disabled') || this.readonly) {
|
|
1710
1714
|
return;
|
|
1711
1715
|
}
|
|
1712
1716
|
if (this.#ddmenu.shown) {
|
|
@@ -1722,7 +1726,7 @@ class Select extends ParsedElement {
|
|
|
1722
1726
|
if (!e.target.closest('button')) {
|
|
1723
1727
|
return;
|
|
1724
1728
|
}
|
|
1725
|
-
if (this.disabled || this.readonly) {
|
|
1729
|
+
if (this.matches(':disabled') || this.readonly) {
|
|
1726
1730
|
return;
|
|
1727
1731
|
}
|
|
1728
1732
|
const idx = [...this.#items.children].indexOf(e.target.closest('ful-item'));
|
|
@@ -1735,7 +1739,7 @@ class Select extends ParsedElement {
|
|
|
1735
1739
|
});
|
|
1736
1740
|
this.#badges.addEventListener('click', (e) => {
|
|
1737
1741
|
e.stopPropagation();
|
|
1738
|
-
if (this.disabled || this.readonly) {
|
|
1742
|
+
if (this.matches(':disabled') || this.readonly) {
|
|
1739
1743
|
return;
|
|
1740
1744
|
}
|
|
1741
1745
|
const idx = [...this.#badges.children].indexOf(e.target);
|
|
@@ -1760,7 +1764,7 @@ class Select extends ParsedElement {
|
|
|
1760
1764
|
this.#input.value = '';
|
|
1761
1765
|
});
|
|
1762
1766
|
this.#input.addEventListener('keydown', (e) => {
|
|
1763
|
-
if (this.disabled || this.readonly) {
|
|
1767
|
+
if (this.matches(':disabled') || this.readonly) {
|
|
1764
1768
|
return;
|
|
1765
1769
|
}
|
|
1766
1770
|
switch (e.code) {
|
|
@@ -1813,7 +1817,7 @@ class Select extends ParsedElement {
|
|
|
1813
1817
|
});
|
|
1814
1818
|
this.#input.addEventListener('input', (e) => {
|
|
1815
1819
|
e.stopPropagation();
|
|
1816
|
-
if (this.disabled || this.readonly) {
|
|
1820
|
+
if (this.matches(':disabled') || this.readonly) {
|
|
1817
1821
|
return;
|
|
1818
1822
|
}
|
|
1819
1823
|
dload();
|
|
@@ -1823,7 +1827,7 @@ class Select extends ParsedElement {
|
|
|
1823
1827
|
if (!this.#multiple) {
|
|
1824
1828
|
this.#values.clear();
|
|
1825
1829
|
}
|
|
1826
|
-
this.#values.set(e.detail.data[0], e.detail.data.slice(1));
|
|
1830
|
+
this.#values.set(this.#coerceKey(e.detail.data[0]), e.detail.data.slice(1));
|
|
1827
1831
|
this.#changed();
|
|
1828
1832
|
this.#syncBadges();
|
|
1829
1833
|
this.#input.focus();
|
|
@@ -1874,10 +1878,36 @@ class Select extends ParsedElement {
|
|
|
1874
1878
|
this.#items.replaceChildren();
|
|
1875
1879
|
this.template('items').withOverlay({ entries: this.#values.entries() }).renderTo(this.#items);
|
|
1876
1880
|
}
|
|
1881
|
+
/**
|
|
1882
|
+
* Coerces a key to the type declared by `k-type`. Keys reach the element from
|
|
1883
|
+
* both worlds: the `value` attribute is text, a loader returns whatever its
|
|
1884
|
+
* endpoint carries. One canonical type keeps the internal Map, which compares
|
|
1885
|
+
* keys strictly, consistent. A key that does not decode is left as it is.
|
|
1886
|
+
*/
|
|
1887
|
+
#coerceKey(k) {
|
|
1888
|
+
switch (this.getAttribute('k-type')) {
|
|
1889
|
+
case 'number': {
|
|
1890
|
+
const n = k === '' ? Number.NaN : Number(k);
|
|
1891
|
+
return Number.isNaN(n) ? k : n;
|
|
1892
|
+
}
|
|
1893
|
+
case 'boolean': {
|
|
1894
|
+
if (k === true || k === 'true') {
|
|
1895
|
+
return true;
|
|
1896
|
+
}
|
|
1897
|
+
if (k === false || k === 'false') {
|
|
1898
|
+
return false;
|
|
1899
|
+
}
|
|
1900
|
+
return k;
|
|
1901
|
+
}
|
|
1902
|
+
default:
|
|
1903
|
+
return String(k);
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1877
1907
|
set value(vs) {
|
|
1878
1908
|
//the csvm mapper yields [] for a missing multiple value, an empty string is
|
|
1879
1909
|
//left alone: it is a usable key for an <option value="">
|
|
1880
|
-
const keys = vs == null ? [] : Array.isArray(vs) ? vs : [vs];
|
|
1910
|
+
const keys = (vs == null ? [] : Array.isArray(vs) ? vs : [vs]).map((k) => this.#coerceKey(k));
|
|
1881
1911
|
//the keys are known synchronously and are all `value` reads, so they are applied
|
|
1882
1912
|
//now: only the labels need the loader, until then a key stands in for its own
|
|
1883
1913
|
this.#values = new Map(keys.map((k) => [k, [k]]));
|
|
@@ -1900,7 +1930,8 @@ class Select extends ParsedElement {
|
|
|
1900
1930
|
}
|
|
1901
1931
|
//label the keys that are still selected: a removal made while the lookup was in
|
|
1902
1932
|
//flight must not be undone by it, and a key the loader does not know is dropped
|
|
1903
|
-
|
|
1933
|
+
//the loader keys are coerced too, so they line up with the assigned ones
|
|
1934
|
+
const resolved = new Map(entries.map((e) => [this.#coerceKey(e[0]), e.slice(1)]));
|
|
1904
1935
|
for (const key of keys) {
|
|
1905
1936
|
if (!this.#values.has(key)) {
|
|
1906
1937
|
continue;
|
|
@@ -1926,15 +1957,17 @@ class Select extends ParsedElement {
|
|
|
1926
1957
|
return [...this.#values.entries()][0] ?? null;
|
|
1927
1958
|
}
|
|
1928
1959
|
get disabled() {
|
|
1929
|
-
|
|
1960
|
+
//the claim only, like a native input: the effective state, claim or disabled
|
|
1961
|
+
//ancestry, is what :disabled matches
|
|
1962
|
+
return this.hasAttribute('disabled');
|
|
1930
1963
|
}
|
|
1931
1964
|
set disabled(d) {
|
|
1932
|
-
|
|
1933
|
-
//also on the host: a form associated element only matches :disabled through its
|
|
1934
|
-
//own attribute, and that is what keeps it out of the submitted values. no reflect
|
|
1935
|
-
//is needed, disabled is deliberately not observed: the platform delivers it
|
|
1936
|
-
//through formDisabledCallback, which also covers a disabled ancestor fieldset
|
|
1965
|
+
//the claim belongs to the author alone, nothing else ever writes it
|
|
1937
1966
|
Attributes.toggle(this, 'disabled', d);
|
|
1967
|
+
//the inner control carries the claim as a native input would: a disabled
|
|
1968
|
+
//fieldset ancestry is left to the browser, which reaches the inner control
|
|
1969
|
+
//as a descendant of the fieldset and re-enables it on its own
|
|
1970
|
+
Attributes.toggle(this.#input, 'disabled', d);
|
|
1938
1971
|
}
|
|
1939
1972
|
get readonly() {
|
|
1940
1973
|
return this.#input.readOnly;
|
|
@@ -2082,15 +2115,17 @@ class RadioGroup extends ParsedElement {
|
|
|
2082
2115
|
});
|
|
2083
2116
|
}
|
|
2084
2117
|
get disabled() {
|
|
2085
|
-
|
|
2118
|
+
//the claim only, like a native input: the effective state, claim or disabled
|
|
2119
|
+
//ancestry, is what :disabled matches
|
|
2120
|
+
return this.hasAttribute('disabled');
|
|
2086
2121
|
}
|
|
2087
2122
|
set disabled(d) {
|
|
2088
|
-
|
|
2089
|
-
//also on the host: a form associated element only matches :disabled through its
|
|
2090
|
-
//own attribute, and that is what keeps it out of the submitted values. no reflect
|
|
2091
|
-
//is needed, disabled is deliberately not observed: the platform delivers it
|
|
2092
|
-
//through formDisabledCallback, which also covers a disabled ancestor fieldset
|
|
2123
|
+
//the claim belongs to the author alone, nothing else ever writes it
|
|
2093
2124
|
Attributes.toggle(this, 'disabled', d);
|
|
2125
|
+
//the group disables through its own fieldset, which carries the claim like
|
|
2126
|
+
//a native input would: a disabled outer ancestry is left to the browser,
|
|
2127
|
+
//which reaches the radios as descendants and re-enables them on its own
|
|
2128
|
+
this.#fieldset.disabled = d;
|
|
2094
2129
|
}
|
|
2095
2130
|
get required() {
|
|
2096
2131
|
return this.#fieldset.getAttribute('aria-required') === 'true';
|
|
@@ -2165,7 +2200,8 @@ class Checkbox extends ParsedElement {
|
|
|
2165
2200
|
const label = fragment.querySelector('label');
|
|
2166
2201
|
label.addEventListener('click', () => {
|
|
2167
2202
|
this.focus();
|
|
2168
|
-
|
|
2203
|
+
//a label is not a form control, the guard must ask the effective state
|
|
2204
|
+
if (this.matches(':disabled') || this.readonly) {
|
|
2169
2205
|
return;
|
|
2170
2206
|
}
|
|
2171
2207
|
this.value = !this.value;
|
|
@@ -2200,15 +2236,17 @@ class Checkbox extends ParsedElement {
|
|
|
2200
2236
|
});
|
|
2201
2237
|
}
|
|
2202
2238
|
get disabled() {
|
|
2203
|
-
|
|
2239
|
+
//the claim only, like a native input: the effective state, claim or disabled
|
|
2240
|
+
//ancestry, is what :disabled matches
|
|
2241
|
+
return this.hasAttribute('disabled');
|
|
2204
2242
|
}
|
|
2205
2243
|
set disabled(d) {
|
|
2206
|
-
|
|
2207
|
-
//also on the host: a form associated element only matches :disabled through its
|
|
2208
|
-
//own attribute, and that is what keeps it out of the submitted values. no reflect
|
|
2209
|
-
//is needed, disabled is deliberately not observed: the platform delivers it
|
|
2210
|
-
//through formDisabledCallback, which also covers a disabled ancestor fieldset
|
|
2244
|
+
//the claim belongs to the author alone, nothing else ever writes it
|
|
2211
2245
|
Attributes.toggle(this, 'disabled', d);
|
|
2246
|
+
//the inner control carries the claim as a native input would: a disabled
|
|
2247
|
+
//fieldset ancestry is left to the browser, which reaches the inner control
|
|
2248
|
+
//as a descendant of the fieldset and re-enables it on its own
|
|
2249
|
+
Attributes.toggle(this.#input, 'disabled', d);
|
|
2212
2250
|
}
|
|
2213
2251
|
get required() {
|
|
2214
2252
|
return this.#input.getAttribute('aria-required') === 'true';
|
|
@@ -2846,8 +2884,10 @@ class InstantFilter extends Input {
|
|
|
2846
2884
|
return super.disabled;
|
|
2847
2885
|
}
|
|
2848
2886
|
set disabled(d) {
|
|
2849
|
-
|
|
2887
|
+
//the claim and the first operand are the base's, the second operand mirrors
|
|
2888
|
+
//the claim like the first one does
|
|
2850
2889
|
super.disabled = d;
|
|
2890
|
+
Attributes.toggle(this.#value2, 'disabled', d);
|
|
2851
2891
|
}
|
|
2852
2892
|
}
|
|
2853
2893
|
|
|
@@ -2962,8 +3002,10 @@ class LocalDateFilter extends Input {
|
|
|
2962
3002
|
return super.disabled;
|
|
2963
3003
|
}
|
|
2964
3004
|
set disabled(d) {
|
|
2965
|
-
|
|
3005
|
+
//the claim and the first operand are the base's, the second operand mirrors
|
|
3006
|
+
//the claim like the first one does
|
|
2966
3007
|
super.disabled = d;
|
|
3008
|
+
Attributes.toggle(this.#value2, 'disabled', d);
|
|
2967
3009
|
}
|
|
2968
3010
|
}
|
|
2969
3011
|
|