loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Convert issue list checkboxes to native (#23596)

Use native instead of fomantic checkboxes in issue list. Benefits
include no more JS pop-in on load and perfect a11y.

Before, with JS pop-in:

<img width="92" alt="Screenshot 2023-03-20 at 17 02 02"
src="https://user-images.githubusercontent.com/115237/226398955-99029a1c-1150-449c-821b-e4165e7446a8.png">

After, Firefox on macOS:

<img width="126" alt="Screenshot 2023-03-20 at 17 01 26"
src="https://user-images.githubusercontent.com/115237/226399018-58df2c32-c2b2-4c78-b7df-7b76523abe21.png">

After, Chrome on macOS:

<img width="79" alt="Screenshot 2023-03-20 at 17 01 42"
src="https://user-images.githubusercontent.com/115237/226399074-947e6279-8dc3-42c2-90b5-b106c471b23d.png">

I opted to not do styling yet but I see that the inconsistency between
browsers may already be reason enough on doing it. I think if we style
them, there should be one global style, including markdown ones which
currently have custom styling.

authored by

silverwind and committed by
GitHub
525b7382 964a057a

+8 -29
+1 -3
templates/repo/issue/list.tmpl
··· 29 29 <div id="issue-filters" class="ui stackable grid"> 30 30 <div class="six wide column"> 31 31 {{if $.CanWriteIssuesOrPulls}} 32 - <div class="ui checkbox issue-checkbox-all gt-vm"> 33 - <input type="checkbox" title="{{.locale.Tr "repo.issues.action_check_all"}}"> 34 - </div> 32 + <input type="checkbox" autocomplete="off" class="issue-checkbox-all gt-vm gt-mr-4" title="{{.locale.Tr "repo.issues.action_check_all"}}"> 35 33 {{end}} 36 34 {{template "repo/issue/openclose" .}} 37 35 </div>
+2 -4
templates/shared/issuelist.tmpl
··· 2 2 {{$approvalCounts := .ApprovalCounts}} 3 3 {{range .Issues}} 4 4 <li class="item gt-df gt-py-3"> 5 - <div class="issue-item-left gt-df"> 5 + <div class="issue-item-left gt-df gt-items-start"> 6 6 {{if $.CanWriteIssuesOrPulls}} 7 - <div class="ui checkbox issue-checkbox"> 8 - <input type="checkbox" data-issue-id={{.ID}} title="{{$.locale.Tr "repo.issues.action_check"}} «{{.Title}}»"> 9 - </div> 7 + <input type="checkbox" autocomplete="off" class="issue-checkbox gt-mt-2 gt-mr-4" data-issue-id={{.ID}} aria-label="{{$.locale.Tr "repo.issues.action_check"}} &quot;{{.Title}}&quot;"> 10 8 {{end}} 11 9 <div class="issue-item-icon"> 12 10 {{if .IsPull}}
+1
web_src/css/helpers.css
··· 24 24 .gt-relative { position: relative !important; } 25 25 .gt-overflow-x-scroll { overflow-x: scroll !important; } 26 26 .gt-cursor-default { cursor: default !important; } 27 + .gt-items-start { align-items: flex-start !important; } 27 28 28 29 .gt-mono { 29 30 font-family: var(--fonts-monospace) !important;
-4
web_src/css/shared/issuelist.css
··· 7 7 color: var(--color-primary) !important; 8 8 } 9 9 10 - .issue.list > .item .issue-checkbox { 11 - margin-top: 1px; 12 - } 13 - 14 10 .issue.list > .item .issue-item-icon svg { 15 11 margin-right: 0.75rem; 16 12 margin-top: 1px;
+4 -18
web_src/js/features/common-issue.js
··· 3 3 import {toggleElem} from '../utils/dom.js'; 4 4 5 5 export function initCommonIssue() { 6 - const $issueSelectAllWrapper = $('.issue-checkbox-all'); 7 - const $issueSelectAll = $('.issue-checkbox-all input'); 8 - const $issueCheckboxes = $('.issue-checkbox input'); 6 + const $issueSelectAll = $('.issue-checkbox-all'); 7 + const $issueCheckboxes = $('.issue-checkbox'); 9 8 10 9 const syncIssueSelectionState = () => { 11 10 const $checked = $issueCheckboxes.filter(':checked'); ··· 23 22 toggleElem($('#issue-filters'), !anyChecked); 24 23 toggleElem($('#issue-actions'), anyChecked); 25 24 // there are two panels but only one select-all checkbox, so move the checkbox to the visible panel 26 - $('#issue-filters, #issue-actions').filter(':visible').find('.column:first').prepend($issueSelectAllWrapper); 25 + $('#issue-filters, #issue-actions').filter(':visible').find('.column:first').prepend($issueSelectAll); 27 26 }; 28 27 29 28 $issueCheckboxes.on('change', syncIssueSelectionState); ··· 38 37 let action = this.getAttribute('data-action'); 39 38 let elementId = this.getAttribute('data-element-id'); 40 39 const url = this.getAttribute('data-url'); 41 - const issueIDs = $('.issue-checkbox').children('input:checked').map((_, el) => { 40 + const issueIDs = $('.issue-checkbox:checked').map((_, el) => { 42 41 return el.getAttribute('data-issue-id'); 43 42 }).get().join(','); 44 43 if (elementId === '0' && url.slice(-9) === '/assignee') { ··· 54 53 issueIDs, 55 54 elementId 56 55 ).then(() => { 57 - // NOTICE: This reset of checkbox state targets Firefox caching behaviour, as the 58 - // checkboxes stay checked after reload 59 - if (action === 'close' || action === 'open') { 60 - // uncheck all checkboxes 61 - $('.issue-checkbox input[type="checkbox"]').each((_, e) => { e.checked = false }); 62 - } 63 56 window.location.reload(); 64 57 }); 65 - }); 66 - 67 - // NOTICE: This event trigger targets Firefox caching behaviour, as the checkboxes stay 68 - // checked after reload trigger checked event, if checkboxes are checked on load 69 - $('.issue-checkbox input[type="checkbox"]:checked').first().each((_, e) => { 70 - e.checked = false; 71 - $(e).trigger('click'); 72 58 }); 73 59 }