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.

Remove jQuery `.attr` from the common issue page functions (#30083)

- Switched from jQuery `attr` to plain javascript `getAttribute` and
`setAttribute`
- Tested most of the functions and they work as before

---------

Signed-off-by: Yarden Shoham <git@yardenshoham.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: delvh <dev.lh@web.de>
(cherry picked from commit e0b018706fa7703ef1759d9a75a1399383715808)

authored by

Yarden Shoham
silverwind
delvh
and committed by
Earl Warren
7e0dfa07 c7091d54

+83 -73
+83 -73
web_src/js/features/repo-issue.js
··· 42 42 } 43 43 44 44 async function updateDeadline(deadlineString) { 45 - hideElem($('#deadline-err-invalid-date')); 46 - $('#deadline-loader').addClass('is-loading'); 45 + hideElem('#deadline-err-invalid-date'); 46 + document.getElementById('deadline-loader')?.classList.add('is-loading'); 47 47 48 48 let realDeadline = null; 49 49 if (deadlineString !== '') { 50 50 const newDate = Date.parse(deadlineString); 51 51 52 52 if (Number.isNaN(newDate)) { 53 - $('#deadline-loader').removeClass('is-loading'); 54 - showElem($('#deadline-err-invalid-date')); 53 + document.getElementById('deadline-loader')?.classList.remove('is-loading'); 54 + showElem('#deadline-err-invalid-date'); 55 55 return false; 56 56 } 57 57 realDeadline = new Date(newDate); 58 58 } 59 59 60 60 try { 61 - const response = await POST($('#update-issue-deadline-form').attr('action'), { 61 + const response = await POST(document.getElementById('update-issue-deadline-form').getAttribute('action'), { 62 62 data: {due_date: realDeadline}, 63 63 }); 64 64 ··· 69 69 } 70 70 } catch (error) { 71 71 console.error(error); 72 - $('#deadline-loader').removeClass('is-loading'); 73 - showElem($('#deadline-err-invalid-date')); 72 + document.getElementById('deadline-loader').classList.remove('is-loading'); 73 + showElem('#deadline-err-invalid-date'); 74 74 } 75 75 } 76 76 ··· 87 87 }); 88 88 } 89 89 90 + /** 91 + * @param {HTMLElement} item 92 + */ 93 + function excludeLabel(item) { 94 + const href = item.getAttribute('href'); 95 + const id = item.getAttribute('data-label-id'); 96 + 97 + const regStr = `labels=((?:-?[0-9]+%2c)*)(${id})((?:%2c-?[0-9]+)*)&`; 98 + const newStr = 'labels=$1-$2$3&'; 99 + 100 + window.location = href.replace(new RegExp(regStr), newStr); 101 + } 102 + 90 103 export function initRepoIssueSidebarList() { 91 104 const repolink = $('#repolink').val(); 92 105 const repoId = $('#repoId').val(); ··· 123 136 fullTextSearch: true, 124 137 }); 125 138 126 - function excludeLabel(item) { 127 - const href = $(item).attr('href'); 128 - const id = $(item).data('label-id'); 129 - 130 - const regStr = `labels=((?:-?[0-9]+%2c)*)(${id})((?:%2c-?[0-9]+)*)&`; 131 - const newStr = 'labels=$1-$2$3&'; 132 - 133 - window.location = href.replace(new RegExp(regStr), newStr); 134 - } 135 - 136 139 $('.menu a.label-filter-item').each(function () { 137 140 $(this).on('click', function (e) { 138 141 if (e.altKey) { ··· 144 147 145 148 $('.menu .ui.dropdown.label-filter').on('keydown', (e) => { 146 149 if (e.altKey && e.keyCode === 13) { 147 - const $selectedItems = $('.menu .ui.dropdown.label-filter .menu .item.selected'); 148 - if ($selectedItems.length > 0) { 149 - excludeLabel($($selectedItems[0])); 150 + const selectedItem = document.querySelector('.menu .ui.dropdown.label-filter .menu .item.selected'); 151 + if (selectedItem) { 152 + excludeLabel(selectedItem); 150 153 } 151 154 } 152 155 }); ··· 166 169 const $parentTimelineGroup = $this.closest('.timeline-item-group'); 167 170 // Check if this was a pending comment. 168 171 if ($conversationHolder.find('.pending-label').length) { 169 - const $counter = $('#review-box .review-comments-counter'); 170 - let num = parseInt($counter.attr('data-pending-comment-number')) - 1 || 0; 172 + const counter = document.querySelector('#review-box .review-comments-counter'); 173 + let num = parseInt(counter?.getAttribute('data-pending-comment-number')) - 1 || 0; 171 174 num = Math.max(num, 0); 172 - $counter.attr('data-pending-comment-number', num); 173 - $counter.text(num); 175 + counter.setAttribute('data-pending-comment-number', num); 176 + counter.textContent = String(num); 174 177 } 175 178 176 179 $(`#${$this.data('comment-id')}`).remove(); ··· 279 282 } 280 283 281 284 export function initRepoPullRequestAllowMaintainerEdit() { 282 - const $checkbox = $('#allow-edits-from-maintainers'); 283 - if (!$checkbox.length) return; 285 + const checkbox = document.getElementById('allow-edits-from-maintainers'); 286 + if (!checkbox) return; 284 287 285 - const promptError = $checkbox.attr('data-prompt-error'); 288 + const $checkbox = $(checkbox); 289 + 290 + const promptError = checkbox.getAttribute('data-prompt-error'); 286 291 $checkbox.checkbox({ 287 292 'onChange': async () => { 288 293 const checked = $checkbox.checkbox('is checked'); 289 - let url = $checkbox.attr('data-url'); 294 + let url = checkbox.getAttribute('data-url'); 290 295 url += '/set_allow_maintainer_edit'; 291 296 $checkbox.checkbox('set disabled'); 292 297 try { ··· 298 303 } 299 304 } catch (error) { 300 305 console.error(error); 301 - showTemporaryTooltip($checkbox[0], promptError); 306 + showTemporaryTooltip(checkbox, promptError); 302 307 } finally { 303 308 $checkbox.checkbox('set enabled'); 304 309 } ··· 325 330 }, 326 331 onChange(_value, _text, $choice) { 327 332 const $form = $choice.closest('form'); 328 - $form.attr('action', `${appSubUrl}/${_text}/issues/new`); 333 + if (!$form.length) return; 334 + 335 + $form[0].setAttribute('action', `${appSubUrl}/${_text}/issues/new`); 329 336 }, 330 337 fullTextSearch: true, 331 338 }); ··· 375 382 window.location.reload(); 376 383 }); 377 384 378 - $(document).on('click', (event) => { 379 - const $urlTarget = $(':target'); 380 - if (!$urlTarget.length) return; 385 + document.addEventListener('click', (e) => { 386 + const urlTarget = document.querySelector(':target'); 387 + if (!urlTarget) return; 381 388 382 - const urlTargetId = $urlTarget.attr('id'); 389 + const urlTargetId = urlTarget.id; 383 390 if (!urlTargetId) return; 384 - if (!/^(issue|pull)(comment)?-\d+$/.test(urlTargetId)) return; 385 391 386 - const $target = $(event.target); 392 + if (!/^(issue|pull)(comment)?-\d+$/.test(urlTargetId)) return; 387 393 388 - if (!$target.closest(`#${urlTargetId}`).length) { 394 + if (!e.target.closest(`#${urlTargetId}`)) { 389 395 const scrollPosition = $(window).scrollTop(); 390 396 window.location.hash = ''; 391 397 $(window).scrollTop(scrollPosition); ··· 419 425 if (window.history.scrollRestoration !== 'manual') { 420 426 window.history.scrollRestoration = 'manual'; 421 427 } 422 - const $commentDiv = $(window.location.hash); 423 - if ($commentDiv) { 428 + const commentDiv = document.querySelector(window.location.hash); 429 + if (commentDiv) { 424 430 // get the name of the parent id 425 - const groupID = $commentDiv.closest('div[id^="code-comments-"]').attr('id'); 431 + const groupID = commentDiv.closest('div[id^="code-comments-"]')?.getAttribute('id'); 426 432 if (groupID && groupID.startsWith('code-comments-')) { 427 433 const id = groupID.slice(14); 428 - const $ancestorDiffBox = $commentDiv.closest('.diff-file-box'); 434 + const ancestorDiffBox = commentDiv.closest('.diff-file-box'); 429 435 // on pages like conversation, there is no diff header 430 - const $diffHeader = $ancestorDiffBox.find('.diff-file-header'); 436 + const diffHeader = ancestorDiffBox?.querySelector('.diff-file-header'); 437 + 431 438 // offset is for scrolling 432 439 let offset = 30; 433 - if ($diffHeader[0]) { 434 - offset += $('.diff-detail-box').outerHeight() + $diffHeader.outerHeight(); 440 + if (diffHeader) { 441 + offset += $('.diff-detail-box').outerHeight() + $(diffHeader).outerHeight(); 435 442 } 436 - $(`#show-outdated-${id}`).addClass('tw-hidden'); 437 - $(`#code-comments-${id}`).removeClass('tw-hidden'); 438 - $(`#code-preview-${id}`).removeClass('tw-hidden'); 439 - $(`#hide-outdated-${id}`).removeClass('tw-hidden'); 443 + 444 + document.getElementById(`show-outdated-${id}`).classList.add('tw-hidden'); 445 + document.getElementById(`code-comments-${id}`).classList.remove('tw-hidden'); 446 + document.getElementById(`code-preview-${id}`).classList.remove('tw-hidden'); 447 + document.getElementById(`hide-outdated-${id}`).classList.remove('tw-hidden'); 440 448 // if the comment box is folded, expand it 441 - if ($ancestorDiffBox.attr('data-folded') && $ancestorDiffBox.attr('data-folded') === 'true') { 442 - setFileFolding($ancestorDiffBox[0], $ancestorDiffBox.find('.fold-file')[0], false); 449 + if (ancestorDiffBox.getAttribute('data-folded') === 'true') { 450 + setFileFolding(ancestorDiffBox, ancestorDiffBox.querySelector('.fold-file'), false); 443 451 } 452 + 444 453 window.scrollTo({ 445 - top: $commentDiv.offset().top - offset, 454 + top: $(commentDiv).offset().top - offset, 446 455 behavior: 'instant', 447 456 }); 448 457 } ··· 529 538 const $commentCloud = $td.find('.comment-code-cloud'); 530 539 if (!$commentCloud.length && !$ntr.find('button[name="pending_review"]').length) { 531 540 try { 532 - const response = await GET($(this).closest('[data-new-comment-url]').attr('data-new-comment-url')); 541 + const response = await GET(this.closest('[data-new-comment-url]')?.getAttribute('data-new-comment-url')); 533 542 const html = await response.text(); 534 543 $td.html(html); 535 544 $td.find("input[name='line']").val(idx); ··· 585 594 }); 586 595 } 587 596 597 + async function pullrequest_targetbranch_change(update_url) { 598 + const targetBranch = $('#pull-target-branch').data('branch'); 599 + const $branchTarget = $('#branch_target'); 600 + if (targetBranch === $branchTarget.text()) { 601 + window.location.reload(); 602 + return false; 603 + } 604 + try { 605 + await POST(update_url, {data: new URLSearchParams({target_branch: targetBranch})}); 606 + } catch (error) { 607 + console.error(error); 608 + } finally { 609 + window.location.reload(); 610 + } 611 + } 612 + 588 613 export function initRepoIssueTitleEdit() { 589 614 // Edit issue title 590 615 const $issueTitle = $('#issue-title'); ··· 607 632 $('#edit-title').on('click', editTitleToggle); 608 633 $('#cancel-edit-title').on('click', editTitleToggle); 609 634 $('#save-edit-title').on('click', editTitleToggle).on('click', async function () { 610 - const pullrequest_targetbranch_change = async function (update_url) { 611 - const targetBranch = $('#pull-target-branch').data('branch'); 612 - const $branchTarget = $('#branch_target'); 613 - if (targetBranch === $branchTarget.text()) { 614 - window.location.reload(); 615 - return false; 616 - } 617 - try { 618 - await POST(update_url, {data: new URLSearchParams({target_branch: targetBranch})}); 619 - } catch (error) { 620 - console.error(error); 621 - } finally { 622 - window.location.reload(); 623 - } 624 - }; 625 - 626 - const pullrequest_target_update_url = $(this).attr('data-target-update-url'); 635 + const pullrequest_target_update_url = this.getAttribute('data-target-update-url'); 627 636 if (!$editInput.val().length || $editInput.val() === $issueTitle.text()) { 628 637 $editInput.val($issueTitle.text()); 629 638 await pullrequest_targetbranch_change(pullrequest_target_update_url); ··· 631 640 try { 632 641 const params = new URLSearchParams(); 633 642 params.append('title', $editInput.val()); 634 - const response = await POST($(this).attr('data-update-url'), {data: params}); 643 + const response = await POST(this.getAttribute('data-update-url'), {data: params}); 635 644 const data = await response.json(); 636 645 $editInput.val(data.title); 637 646 $issueTitle.text(data.title); ··· 671 680 // * normal new issue/pr page, no status-button 672 681 // * issue/pr view page, with comment form, has status-button 673 682 const opts = {}; 674 - const $statusButton = $('#status-button'); 675 - if ($statusButton.length) { 683 + const statusButton = document.getElementById('status-button'); 684 + if (statusButton) { 676 685 opts.onContentChanged = (editor) => { 677 - $statusButton.text($statusButton.attr(editor.value().trim() ? 'data-status-and-comment' : 'data-status')); 686 + const statusText = statusButton.getAttribute(editor.value().trim() ? 'data-status-and-comment' : 'data-status'); 687 + statusButton.textContent = statusText; 678 688 }; 679 689 } 680 690 initComboMarkdownEditor($commentForm.find('.combo-markdown-editor'), opts);