From 8fd15990c5c8980caf2b9ffefc0b3427efacdc04 Mon Sep 17 00:00:00 2001 From: silverwind Date: Fri, 29 Mar 2024 05:56:01 +0100 Subject: Remove fomantic checkbox module (#30162) CSS is pretty slim already and the `.ui.toggle.checkbox` sliders on admin page also still work. The only necessary JS is the one that links `input` and `label` so that it can be toggled via label. All checkboxes except the markdown ones render at `--checkbox-size: 16px` now. Screenshot 2024-03-28 at 22 15 10 Screenshot 2024-03-28 at 21 00 07 Screenshot 2024-03-28 at 22 14 34 --------- Co-authored-by: delvh --- web_src/js/features/admin/common.js | 23 +++++++++++------ web_src/js/features/common-global.js | 2 -- web_src/js/features/repo-issue.js | 44 ++++++++++++++------------------- web_src/js/modules/fomantic.js | 2 -- web_src/js/modules/fomantic/aria.md | 17 +++++-------- web_src/js/modules/fomantic/checkbox.js | 43 ++++++++------------------------ 6 files changed, 50 insertions(+), 81 deletions(-) (limited to 'web_src/js') diff --git a/web_src/js/features/admin/common.js b/web_src/js/features/admin/common.js index 8a88996742..f388b1122e 100644 --- a/web_src/js/features/admin/common.js +++ b/web_src/js/features/admin/common.js @@ -218,17 +218,24 @@ export function initAdminCommon() { }); // Select actions - const $checkboxes = $('.select.table .ui.checkbox'); + const checkboxes = document.querySelectorAll('.select.table .ui.checkbox input'); + $('.select.action').on('click', function () { switch ($(this).data('action')) { case 'select-all': - $checkboxes.checkbox('check'); + for (const checkbox of checkboxes) { + checkbox.checked = true; + } break; case 'deselect-all': - $checkboxes.checkbox('uncheck'); + for (const checkbox of checkboxes) { + checkbox.checked = false; + } break; case 'inverse': - $checkboxes.checkbox('toggle'); + for (const checkbox of checkboxes) { + checkbox.checked = !checkbox.checked; + } break; } }); @@ -236,11 +243,11 @@ export function initAdminCommon() { e.preventDefault(); this.classList.add('is-loading', 'disabled'); const data = new FormData(); - $checkboxes.each(function () { - if ($(this).checkbox('is checked')) { - data.append('ids[]', this.getAttribute('data-id')); + for (const checkbox of checkboxes) { + if (checkbox.checked) { + data.append('ids[]', checkbox.closest('.ui.checkbox').getAttribute('data-id')); } - }); + } await POST(this.getAttribute('data-link'), {data}); window.location.href = this.getAttribute('data-redirect'); }); diff --git a/web_src/js/features/common-global.js b/web_src/js/features/common-global.js index ce702f041f..009dbd9421 100644 --- a/web_src/js/features/common-global.js +++ b/web_src/js/features/common-global.js @@ -195,8 +195,6 @@ export function initGlobalCommon() { $uiDropdowns.filter('.upward').dropdown('setting', 'direction', 'upward'); $uiDropdowns.filter('.downward').dropdown('setting', 'direction', 'downward'); - $('.ui.checkbox').checkbox(); - $('.tabular.menu .item').tab(); initSubmitEventPolyfill(); diff --git a/web_src/js/features/repo-issue.js b/web_src/js/features/repo-issue.js index 47b4d5f71c..bb45c6ae57 100644 --- a/web_src/js/features/repo-issue.js +++ b/web_src/js/features/repo-issue.js @@ -282,32 +282,26 @@ export function initRepoPullRequestMergeInstruction() { } export function initRepoPullRequestAllowMaintainerEdit() { - const checkbox = document.getElementById('allow-edits-from-maintainers'); - if (!checkbox) return; - - const $checkbox = $(checkbox); - - const promptError = checkbox.getAttribute('data-prompt-error'); - $checkbox.checkbox({ - 'onChange': async () => { - const checked = $checkbox.checkbox('is checked'); - let url = checkbox.getAttribute('data-url'); - url += '/set_allow_maintainer_edit'; - $checkbox.checkbox('set disabled'); - try { - const response = await POST(url, { - data: {allow_maintainer_edit: checked}, - }); - if (!response.ok) { - throw new Error('Failed to update maintainer edit permission'); - } - } catch (error) { - console.error(error); - showTemporaryTooltip(checkbox, promptError); - } finally { - $checkbox.checkbox('set enabled'); + const wrapper = document.getElementById('allow-edits-from-maintainers'); + if (!wrapper) return; + + wrapper.querySelector('input[type="checkbox"]')?.addEventListener('change', async (e) => { + const checked = e.target.checked; + const url = `${wrapper.getAttribute('data-url')}/set_allow_maintainer_edit`; + wrapper.classList.add('is-loading'); + e.target.disabled = true; + try { + const response = await POST(url, {data: {allow_maintainer_edit: checked}}); + if (!response.ok) { + throw new Error('Failed to update maintainer edit permission'); } - }, + } catch (error) { + console.error(error); + showTemporaryTooltip(wrapper, wrapper.getAttribute('data-prompt-error')); + } finally { + wrapper.classList.remove('is-loading'); + e.target.disabled = false; + } }); } diff --git a/web_src/js/modules/fomantic.js b/web_src/js/modules/fomantic.js index 6aafdd5ddc..d205c2b2ee 100644 --- a/web_src/js/modules/fomantic.js +++ b/web_src/js/modules/fomantic.js @@ -11,8 +11,6 @@ export const fomanticMobileScreen = window.matchMedia('only screen and (max-widt export function initGiteaFomantic() { // Silence fomantic's error logging when tabs are used without a target content element $.fn.tab.settings.silent = true; - // Disable the behavior of fomantic to toggle the checkbox when you press enter on a checkbox element. - $.fn.checkbox.settings.enableEnterKey = false; // By default, use "exact match" for full text search $.fn.dropdown.settings.fullTextSearch = 'exact'; diff --git a/web_src/js/modules/fomantic/aria.md b/web_src/js/modules/fomantic/aria.md index f639233346..5836a34506 100644 --- a/web_src/js/modules/fomantic/aria.md +++ b/web_src/js/modules/fomantic/aria.md @@ -41,24 +41,19 @@ The ideal checkboxes should be: ``` -However, related CSS styles aren't supported (not implemented) yet, so at the moment, -almost all the checkboxes are still using Fomantic UI checkbox. - -## Fomantic UI Checkbox +However, the templates still have the Fomantic-style HTML layout: ```html
- +
``` -Then the JS `$.checkbox()` should be called to make it work with keyboard and label-clicking, -then it works like the ideal checkboxes. - -There is still a problem: Fomantic UI checkbox is not friendly to screen readers, -so we add IDs to all the Fomantic UI checkboxes automatically by JS. -If the `label` part is empty, then the checkbox needs to get the `aria-label` attribute manually. +We call `initAriaCheckboxPatch` to link the `input` and `label` which makes clicking the +label etc. work. There is still a problem: These checkboxes are not friendly to screen readers, +so we add IDs to all the Fomantic UI checkboxes automatically by JS. If the `label` part is empty, +then the checkbox needs to get the `aria-label` attribute manually. # Fomantic Dropdown diff --git a/web_src/js/modules/fomantic/checkbox.js b/web_src/js/modules/fomantic/checkbox.js index 08af1c2eb6..ffe853b28f 100644 --- a/web_src/js/modules/fomantic/checkbox.js +++ b/web_src/js/modules/fomantic/checkbox.js @@ -1,38 +1,15 @@ -import $ from 'jquery'; import {generateAriaId} from './base.js'; -const ariaPatchKey = '_giteaAriaPatchCheckbox'; -const fomanticCheckboxFn = $.fn.checkbox; - -// use our own `$.fn.checkbox` to patch Fomantic's checkbox module export function initAriaCheckboxPatch() { - if ($.fn.checkbox === ariaCheckboxFn) throw new Error('initAriaCheckboxPatch could only be called once'); - $.fn.checkbox = ariaCheckboxFn; - ariaCheckboxFn.settings = fomanticCheckboxFn.settings; -} - -// the patched `$.fn.checkbox` checkbox function -// * it does the one-time attaching on the first call -function ariaCheckboxFn(...args) { - const ret = fomanticCheckboxFn.apply(this, args); - for (const el of this) { - if (el[ariaPatchKey]) continue; - attachInit(el); + // link the label and the input element so it's clickable and accessible + for (const el of document.querySelectorAll('.ui.checkbox')) { + if (el.hasAttribute('data-checkbox-patched')) continue; + const label = el.querySelector('label'); + const input = el.querySelector('input'); + if (!label || !input || input.getAttribute('id') || label.getAttribute('for')) continue; + const id = generateAriaId(); + input.setAttribute('id', id); + label.setAttribute('for', id); + el.setAttribute('data-checkbox-patched', 'true'); } - return ret; -} - -function attachInit(el) { - // Fomantic UI checkbox needs to be something like:
- // It doesn't work well with - // To make it work with aria, the "id"/"for" attributes are necessary, so add them automatically if missing. - // In the future, refactor to use native checkbox directly, then this patch could be removed. - el[ariaPatchKey] = {}; // record that this element has been patched - const label = el.querySelector('label'); - const input = el.querySelector('input'); - if (!label || !input || input.getAttribute('id')) return; - - const id = generateAriaId(); - input.setAttribute('id', id); - label.setAttribute('for', id); } -- cgit v1.2.3