Refactor repo-diff.ts (#33746)

Remove jQuery
This commit is contained in:
wxiaoguang
2025-02-28 16:37:16 +08:00
committed by GitHub
parent aba96f65cd
commit 4e56d5f39f
2 changed files with 52 additions and 67 deletions

View File

@ -1,4 +1,3 @@
import $ from 'jquery';
import {initCompReactionSelector} from './comp/ReactionSelector.ts'; import {initCompReactionSelector} from './comp/ReactionSelector.ts';
import {initRepoIssueContentHistory} from './repo-issue-content.ts'; import {initRepoIssueContentHistory} from './repo-issue-content.ts';
import {initDiffFileTree} from './repo-diff-filetree.ts'; import {initDiffFileTree} from './repo-diff-filetree.ts';
@ -7,35 +6,28 @@ import {validateTextareaNonEmpty} from './comp/ComboMarkdownEditor.ts';
import {initViewedCheckboxListenerFor, countAndUpdateViewedFiles, initExpandAndCollapseFilesButton} from './pull-view-file.ts'; import {initViewedCheckboxListenerFor, countAndUpdateViewedFiles, initExpandAndCollapseFilesButton} from './pull-view-file.ts';
import {initImageDiff} from './imagediff.ts'; import {initImageDiff} from './imagediff.ts';
import {showErrorToast} from '../modules/toast.ts'; import {showErrorToast} from '../modules/toast.ts';
import { import {submitEventSubmitter, queryElemSiblings, hideElem, showElem, animateOnce, addDelegatedEventListener, createElementFromHTML, queryElems} from '../utils/dom.ts';
submitEventSubmitter,
queryElemSiblings,
hideElem,
showElem,
animateOnce,
addDelegatedEventListener,
createElementFromHTML,
} from '../utils/dom.ts';
import {POST, GET} from '../modules/fetch.ts'; import {POST, GET} from '../modules/fetch.ts';
import {fomanticQuery} from '../modules/fomantic/base.ts'; import {fomanticQuery} from '../modules/fomantic/base.ts';
import {createTippy} from '../modules/tippy.ts'; import {createTippy} from '../modules/tippy.ts';
import {invertFileFolding} from './file-fold.ts'; import {invertFileFolding} from './file-fold.ts';
import {parseDom} from '../utils.ts';
const {i18n} = window.config; const {i18n} = window.config;
function initRepoDiffFileViewToggle() { function initRepoDiffFileViewToggle() {
$('.file-view-toggle').on('click', function () { // switch between "rendered" and "source", for image and CSV files
for (const el of queryElemSiblings(this)) { // FIXME: this event listener is not correctly added to "load more files"
el.classList.remove('active'); queryElems(document, '.file-view-toggle', (btn) => btn.addEventListener('click', () => {
} queryElemSiblings(btn, '.file-view-toggle', (el) => el.classList.remove('active'));
this.classList.add('active'); btn.classList.add('active');
const target = document.querySelector(this.getAttribute('data-toggle-selector')); const target = document.querySelector(btn.getAttribute('data-toggle-selector'));
if (!target) return; if (!target) throw new Error('Target element not found');
hideElem(queryElemSiblings(target)); hideElem(queryElemSiblings(target));
showElem(target); showElem(target);
}); }));
} }
function initRepoDiffConversationForm() { function initRepoDiffConversationForm() {
@ -103,22 +95,23 @@ function initRepoDiffConversationForm() {
} }
}); });
$(document).on('click', '.resolve-conversation', async function (e) { addDelegatedEventListener(document, 'click', '.resolve-conversation', async (el, e) => {
e.preventDefault(); e.preventDefault();
const comment_id = $(this).data('comment-id'); const comment_id = el.getAttribute('data-comment-id');
const origin = $(this).data('origin'); const origin = el.getAttribute('data-origin');
const action = $(this).data('action'); const action = el.getAttribute('data-action');
const url = $(this).data('update-url'); const url = el.getAttribute('data-update-url');
try { try {
const response = await POST(url, {data: new URLSearchParams({origin, action, comment_id})}); const response = await POST(url, {data: new URLSearchParams({origin, action, comment_id})});
const data = await response.text(); const data = await response.text();
if ($(this).closest('.conversation-holder').length) { const elConversationHolder = el.closest('.conversation-holder');
const $conversation = $(data); if (elConversationHolder) {
$(this).closest('.conversation-holder').replaceWith($conversation); const elNewConversation = createElementFromHTML(data);
$conversation.find('.dropdown').dropdown(); elConversationHolder.replaceWith(elNewConversation);
initCompReactionSelector($conversation[0]); queryElems(elConversationHolder, '.ui.dropdown:not(.custom)', (el) => fomanticQuery(el).dropdown());
initCompReactionSelector(elNewConversation);
} else { } else {
window.location.reload(); window.location.reload();
} }
@ -128,24 +121,19 @@ function initRepoDiffConversationForm() {
}); });
} }
export function initRepoDiffConversationNav() { function initRepoDiffConversationNav() {
// Previous/Next code review conversation // Previous/Next code review conversation
$(document).on('click', '.previous-conversation', (e) => { addDelegatedEventListener(document, 'click', '.previous-conversation, .next-conversation', (el, e) => {
const $conversation = $(e.currentTarget).closest('.comment-code-cloud'); e.preventDefault();
const $conversations = $('.comment-code-cloud:not(.tw-hidden)'); const isPrevious = el.matches('.previous-conversation');
const index = $conversations.index($conversation); const elCurConversation = el.closest('.comment-code-cloud');
const previousIndex = index > 0 ? index - 1 : $conversations.length - 1; const elAllConversations = document.querySelectorAll('.comment-code-cloud:not(.tw-hidden)');
const $previousConversation = $conversations.eq(previousIndex); const index = Array.from(elAllConversations).indexOf(elCurConversation);
const anchor = $previousConversation.find('.comment').first()[0].getAttribute('id'); const previousIndex = index > 0 ? index - 1 : elAllConversations.length - 1;
window.location.href = `#${anchor}`; const nextIndex = index < elAllConversations.length - 1 ? index + 1 : 0;
}); const navIndex = isPrevious ? previousIndex : nextIndex;
$(document).on('click', '.next-conversation', (e) => { const elNavConversation = elAllConversations[navIndex];
const $conversation = $(e.currentTarget).closest('.comment-code-cloud'); const anchor = elNavConversation.querySelector('.comment').id;
const $conversations = $('.comment-code-cloud:not(.tw-hidden)');
const index = $conversations.index($conversation);
const nextIndex = index < $conversations.length - 1 ? index + 1 : 0;
const $nextConversation = $conversations.eq(nextIndex);
const anchor = $nextConversation.find('.comment').first()[0].getAttribute('id');
window.location.href = `#${anchor}`; window.location.href = `#${anchor}`;
}); });
} }
@ -161,7 +149,7 @@ function initDiffHeaderPopup() {
// Will be called when the show more (files) button has been pressed // Will be called when the show more (files) button has been pressed
function onShowMoreFiles() { function onShowMoreFiles() {
// FIXME: here the init calls are incomplete: at least it misses dropdown & initCompReactionSelector // FIXME: here the init calls are incomplete: at least it misses dropdown & initCompReactionSelector & initRepoDiffFileViewToggle
initRepoIssueContentHistory(); initRepoIssueContentHistory();
initViewedCheckboxListenerFor(); initViewedCheckboxListenerFor();
countAndUpdateViewedFiles(); countAndUpdateViewedFiles();
@ -179,10 +167,11 @@ async function loadMoreFiles(btn: Element): Promise<boolean> {
try { try {
const response = await GET(url); const response = await GET(url);
const resp = await response.text(); const resp = await response.text();
const $resp = $(resp); const respDoc = parseDom(resp, 'text/html');
const respFileBoxes = respDoc.querySelector('#diff-file-boxes');
// the response is a full HTML page, we need to extract the relevant contents: // the response is a full HTML page, we need to extract the relevant contents:
// * append the newly loaded file list items to the existing list // * append the newly loaded file list items to the existing list
$('#diff-incomplete').replaceWith($resp.find('#diff-file-boxes').children()); document.querySelector('#diff-incomplete').replaceWith(...Array.from(respFileBoxes.children));
onShowMoreFiles(); onShowMoreFiles();
return true; return true;
} catch (error) { } catch (error) {
@ -200,31 +189,27 @@ function initRepoDiffShowMore() {
loadMoreFiles(el); loadMoreFiles(el);
}); });
$(document).on('click', 'a.diff-load-button', async (e) => { addDelegatedEventListener(document, 'click', 'a.diff-load-button', async (el, e) => {
e.preventDefault(); e.preventDefault();
const $target = $(e.target); if (el.classList.contains('disabled')) return;
if (e.target.classList.contains('disabled')) { el.classList.add('disabled');
return; const url = el.getAttribute('data-href');
}
e.target.classList.add('disabled');
const url = $target.data('href');
try { try {
const response = await GET(url); const response = await GET(url);
const resp = await response.text(); const resp = await response.text();
const respDoc = parseDom(resp, 'text/html');
if (!resp) { const respFileBody = respDoc.querySelector('#diff-file-boxes .diff-file-body .file-body');
return; el.parentElement.replaceWith(...Array.from(respFileBody.children));
} // FIXME: calling onShowMoreFiles is not quite right here.
$target.parent().replaceWith($(resp).find('#diff-file-boxes .diff-file-body .file-body').children()); // But since onShowMoreFiles mixes "init diff box" and "init diff body" together,
// so it still needs to call it to make the "ImageDiff" and something similar work.
onShowMoreFiles(); onShowMoreFiles();
} catch (error) { } catch (error) {
console.error('Error:', error); console.error('Error:', error);
} finally { } finally {
e.target.classList.remove('disabled'); el.classList.remove('disabled');
} }
}); });
} }
@ -262,8 +247,10 @@ function initRepoDiffHashChangeListener() {
} }
export function initRepoDiffView() { export function initRepoDiffView() {
initRepoDiffConversationForm(); initRepoDiffConversationForm(); // such form appears on the "conversation" page and "diff" page
if (!$('#diff-file-boxes').length) return;
if (!document.querySelector('#diff-file-boxes')) return;
initRepoDiffConversationNav(); // "previous" and "next" buttons only appear on "diff" page
initDiffFileTree(); initDiffFileTree();
initDiffCommitSelect(); initDiffCommitSelect();
initRepoDiffShowMore(); initRepoDiffShowMore();

View File

@ -9,7 +9,6 @@ import {initUnicodeEscapeButton} from './repo-unicode-escape.ts';
import {initRepoCloneButtons} from './repo-common.ts'; import {initRepoCloneButtons} from './repo-common.ts';
import {initCitationFileCopyContent} from './citation.ts'; import {initCitationFileCopyContent} from './citation.ts';
import {initCompLabelEdit} from './comp/LabelEdit.ts'; import {initCompLabelEdit} from './comp/LabelEdit.ts';
import {initRepoDiffConversationNav} from './repo-diff.ts';
import {initCompReactionSelector} from './comp/ReactionSelector.ts'; import {initCompReactionSelector} from './comp/ReactionSelector.ts';
import {initRepoSettings} from './repo-settings.ts'; import {initRepoSettings} from './repo-settings.ts';
import {initRepoPullRequestMergeForm} from './repo-issue-pr-form.ts'; import {initRepoPullRequestMergeForm} from './repo-issue-pr-form.ts';
@ -64,7 +63,6 @@ export function initRepository() {
initRepoIssueWipToggle(); initRepoIssueWipToggle();
initRepoIssueComments(); initRepoIssueComments();
initRepoDiffConversationNav();
initRepoIssueReferenceIssue(); initRepoIssueReferenceIssue();
initRepoIssueCommentDelete(); initRepoIssueCommentDelete();