diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl
index c0411cfc5..0cd2201c4 100644
--- a/templates/repo/settings/options.tmpl
+++ b/templates/repo/settings/options.tmpl
@@ -9,8 +9,8 @@
{{.CsrfTokenHtml}}
-
-
+
+
@@ -898,8 +898,8 @@
-
-
+
+
@@ -929,8 +929,8 @@
-
-
+
+
@@ -961,8 +961,8 @@
-
-
+
+
@@ -1031,8 +1031,8 @@
-
-
+
+
diff --git a/web_src/js/modules/fomantic.js b/web_src/js/modules/fomantic.js
index d205c2b2e..c04bc6e86 100644
--- a/web_src/js/modules/fomantic.js
+++ b/web_src/js/modules/fomantic.js
@@ -1,6 +1,7 @@
import $ from 'jquery';
import {initFomanticApiPatch} from './fomantic/api.js';
import {initAriaCheckboxPatch} from './fomantic/checkbox.js';
+import {initAriaFormFieldPatch} from './fomantic/form.js';
import {initAriaDropdownPatch} from './fomantic/dropdown.js';
import {initAriaModalPatch} from './fomantic/modal.js';
import {initFomanticTransition} from './fomantic/transition.js';
@@ -27,6 +28,7 @@ export function initGiteaFomantic() {
// Use the patches to improve accessibility, these patches are designed to be as independent as possible, make it easy to modify or remove in the future.
initAriaCheckboxPatch();
+ initAriaFormFieldPatch();
initAriaDropdownPatch();
initAriaModalPatch();
}
diff --git a/web_src/js/modules/fomantic/base.js b/web_src/js/modules/fomantic/base.js
index c4a01038b..7574fdd25 100644
--- a/web_src/js/modules/fomantic/base.js
+++ b/web_src/js/modules/fomantic/base.js
@@ -3,3 +3,16 @@ let ariaIdCounter = 0;
export function generateAriaId() {
return `_aria_auto_id_${ariaIdCounter++}`;
}
+
+export function linkLabelAndInput(label, input) {
+ const labelFor = label.getAttribute('for');
+ const inputId = input.getAttribute('id');
+
+ if (inputId && !labelFor) { // missing "for"
+ label.setAttribute('for', inputId);
+ } else if (!inputId && !labelFor) { // missing both "id" and "for"
+ const id = generateAriaId();
+ input.setAttribute('id', id);
+ label.setAttribute('for', id);
+ }
+}
diff --git a/web_src/js/modules/fomantic/checkbox.js b/web_src/js/modules/fomantic/checkbox.js
index 7f2b34029..ed77406cc 100644
--- a/web_src/js/modules/fomantic/checkbox.js
+++ b/web_src/js/modules/fomantic/checkbox.js
@@ -1,4 +1,4 @@
-import {generateAriaId} from './base.js';
+import {linkLabelAndInput} from './base.js';
export function initAriaCheckboxPatch() {
// link the label and the input element so it's clickable and accessible
@@ -7,18 +7,7 @@ export function initAriaCheckboxPatch() {
const label = el.querySelector('label');
const input = el.querySelector('input');
if (!label || !input) continue;
- const inputId = input.getAttribute('id');
- const labelFor = label.getAttribute('for');
-
- if (inputId && !labelFor) { // missing "for"
- label.setAttribute('for', inputId);
- } else if (!inputId && !labelFor) { // missing both "id" and "for"
- const id = generateAriaId();
- input.setAttribute('id', id);
- label.setAttribute('for', id);
- } else {
- continue;
- }
+ linkLabelAndInput(label, input);
el.setAttribute('data-checkbox-patched', 'true');
}
}
diff --git a/web_src/js/modules/fomantic/form.js b/web_src/js/modules/fomantic/form.js
new file mode 100644
index 000000000..3bb005890
--- /dev/null
+++ b/web_src/js/modules/fomantic/form.js
@@ -0,0 +1,13 @@
+import {linkLabelAndInput} from './base.js';
+
+export function initAriaFormFieldPatch() {
+ // link the label and the input element so it's clickable and accessible
+ for (const el of document.querySelectorAll('.ui.form .field')) {
+ if (el.hasAttribute('data-field-patched')) continue;
+ const label = el.querySelector(':scope > label');
+ const input = el.querySelector(':scope > input');
+ if (!label || !input) continue;
+ linkLabelAndInput(label, input);
+ el.setAttribute('data-field-patched', 'true');
+ }
+}