mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-30 19:08:37 +00:00 
			
		
		
		
	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. <img width="174" alt="Screenshot 2024-03-28 at 22 15 10" src="https://github.com/go-gitea/gitea/assets/115237/3455c1bb-166b-47e4-9847-2d20dd1f04db"> <img width="499" alt="Screenshot 2024-03-28 at 21 00 07" src="https://github.com/go-gitea/gitea/assets/115237/412be2b3-d5a0-478a-b17b-43e6bc12e8ce"> <img width="83" alt="Screenshot 2024-03-28 at 22 14 34" src="https://github.com/go-gitea/gitea/assets/115237/d8c89838-a420-4723-8c49-89405bb39474"> --------- Co-authored-by: delvh <dev.lh@web.de>
This commit is contained in:
		| @@ -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'); | ||||
|     }); | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -282,32 +282,26 @@ export function initRepoPullRequestMergeInstruction() { | ||||
| } | ||||
|  | ||||
| export function initRepoPullRequestAllowMaintainerEdit() { | ||||
|   const checkbox = document.getElementById('allow-edits-from-maintainers'); | ||||
|   if (!checkbox) return; | ||||
|   const wrapper = document.getElementById('allow-edits-from-maintainers'); | ||||
|   if (!wrapper) 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'); | ||||
|   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; | ||||
|     } | ||||
|   }); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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'; | ||||
|   | ||||
| @@ -41,24 +41,19 @@ The ideal checkboxes should be: | ||||
| <label><input type="checkbox"> ... </label> | ||||
| ``` | ||||
|  | ||||
| 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 | ||||
| <div class="ui checkbox"> | ||||
|   <input type="checkbox"> <!-- class "hidden" will be added by $.checkbox() --> | ||||
|   <input type="checkbox"> | ||||
|   <label>...</label> | ||||
| </div> | ||||
| ``` | ||||
|  | ||||
| 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 | ||||
|  | ||||
|   | ||||
| @@ -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: <div class="ui checkbox"><label /><input /></div> | ||||
|   // It doesn't work well with <label><input />...</label> | ||||
|   // 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); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user