Skip to content

Commit 4e56d5f

Browse files
authored
Refactor repo-diff.ts (#33746)
Remove jQuery
1 parent aba96f6 commit 4e56d5f

File tree

2 files changed

+52
-67
lines changed

2 files changed

+52
-67
lines changed

web_src/js/features/repo-diff.ts

Lines changed: 52 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import $ from 'jquery';
21
import {initCompReactionSelector} from './comp/ReactionSelector.ts';
32
import {initRepoIssueContentHistory} from './repo-issue-content.ts';
43
import {initDiffFileTree} from './repo-diff-filetree.ts';
@@ -7,35 +6,28 @@ import {validateTextareaNonEmpty} from './comp/ComboMarkdownEditor.ts';
76
import {initViewedCheckboxListenerFor, countAndUpdateViewedFiles, initExpandAndCollapseFilesButton} from './pull-view-file.ts';
87
import {initImageDiff} from './imagediff.ts';
98
import {showErrorToast} from '../modules/toast.ts';
10-
import {
11-
submitEventSubmitter,
12-
queryElemSiblings,
13-
hideElem,
14-
showElem,
15-
animateOnce,
16-
addDelegatedEventListener,
17-
createElementFromHTML,
18-
} from '../utils/dom.ts';
9+
import {submitEventSubmitter, queryElemSiblings, hideElem, showElem, animateOnce, addDelegatedEventListener, createElementFromHTML, queryElems} from '../utils/dom.ts';
1910
import {POST, GET} from '../modules/fetch.ts';
2011
import {fomanticQuery} from '../modules/fomantic/base.ts';
2112
import {createTippy} from '../modules/tippy.ts';
2213
import {invertFileFolding} from './file-fold.ts';
14+
import {parseDom} from '../utils.ts';
2315

2416
const {i18n} = window.config;
2517

2618
function initRepoDiffFileViewToggle() {
27-
$('.file-view-toggle').on('click', function () {
28-
for (const el of queryElemSiblings(this)) {
29-
el.classList.remove('active');
30-
}
31-
this.classList.add('active');
19+
// switch between "rendered" and "source", for image and CSV files
20+
// FIXME: this event listener is not correctly added to "load more files"
21+
queryElems(document, '.file-view-toggle', (btn) => btn.addEventListener('click', () => {
22+
queryElemSiblings(btn, '.file-view-toggle', (el) => el.classList.remove('active'));
23+
btn.classList.add('active');
3224

33-
const target = document.querySelector(this.getAttribute('data-toggle-selector'));
34-
if (!target) return;
25+
const target = document.querySelector(btn.getAttribute('data-toggle-selector'));
26+
if (!target) throw new Error('Target element not found');
3527

3628
hideElem(queryElemSiblings(target));
3729
showElem(target);
38-
});
30+
}));
3931
}
4032

4133
function initRepoDiffConversationForm() {
@@ -103,22 +95,23 @@ function initRepoDiffConversationForm() {
10395
}
10496
});
10597

106-
$(document).on('click', '.resolve-conversation', async function (e) {
98+
addDelegatedEventListener(document, 'click', '.resolve-conversation', async (el, e) => {
10799
e.preventDefault();
108-
const comment_id = $(this).data('comment-id');
109-
const origin = $(this).data('origin');
110-
const action = $(this).data('action');
111-
const url = $(this).data('update-url');
100+
const comment_id = el.getAttribute('data-comment-id');
101+
const origin = el.getAttribute('data-origin');
102+
const action = el.getAttribute('data-action');
103+
const url = el.getAttribute('data-update-url');
112104

113105
try {
114106
const response = await POST(url, {data: new URLSearchParams({origin, action, comment_id})});
115107
const data = await response.text();
116108

117-
if ($(this).closest('.conversation-holder').length) {
118-
const $conversation = $(data);
119-
$(this).closest('.conversation-holder').replaceWith($conversation);
120-
$conversation.find('.dropdown').dropdown();
121-
initCompReactionSelector($conversation[0]);
109+
const elConversationHolder = el.closest('.conversation-holder');
110+
if (elConversationHolder) {
111+
const elNewConversation = createElementFromHTML(data);
112+
elConversationHolder.replaceWith(elNewConversation);
113+
queryElems(elConversationHolder, '.ui.dropdown:not(.custom)', (el) => fomanticQuery(el).dropdown());
114+
initCompReactionSelector(elNewConversation);
122115
} else {
123116
window.location.reload();
124117
}
@@ -128,24 +121,19 @@ function initRepoDiffConversationForm() {
128121
});
129122
}
130123

131-
export function initRepoDiffConversationNav() {
124+
function initRepoDiffConversationNav() {
132125
// Previous/Next code review conversation
133-
$(document).on('click', '.previous-conversation', (e) => {
134-
const $conversation = $(e.currentTarget).closest('.comment-code-cloud');
135-
const $conversations = $('.comment-code-cloud:not(.tw-hidden)');
136-
const index = $conversations.index($conversation);
137-
const previousIndex = index > 0 ? index - 1 : $conversations.length - 1;
138-
const $previousConversation = $conversations.eq(previousIndex);
139-
const anchor = $previousConversation.find('.comment').first()[0].getAttribute('id');
140-
window.location.href = `#${anchor}`;
141-
});
142-
$(document).on('click', '.next-conversation', (e) => {
143-
const $conversation = $(e.currentTarget).closest('.comment-code-cloud');
144-
const $conversations = $('.comment-code-cloud:not(.tw-hidden)');
145-
const index = $conversations.index($conversation);
146-
const nextIndex = index < $conversations.length - 1 ? index + 1 : 0;
147-
const $nextConversation = $conversations.eq(nextIndex);
148-
const anchor = $nextConversation.find('.comment').first()[0].getAttribute('id');
126+
addDelegatedEventListener(document, 'click', '.previous-conversation, .next-conversation', (el, e) => {
127+
e.preventDefault();
128+
const isPrevious = el.matches('.previous-conversation');
129+
const elCurConversation = el.closest('.comment-code-cloud');
130+
const elAllConversations = document.querySelectorAll('.comment-code-cloud:not(.tw-hidden)');
131+
const index = Array.from(elAllConversations).indexOf(elCurConversation);
132+
const previousIndex = index > 0 ? index - 1 : elAllConversations.length - 1;
133+
const nextIndex = index < elAllConversations.length - 1 ? index + 1 : 0;
134+
const navIndex = isPrevious ? previousIndex : nextIndex;
135+
const elNavConversation = elAllConversations[navIndex];
136+
const anchor = elNavConversation.querySelector('.comment').id;
149137
window.location.href = `#${anchor}`;
150138
});
151139
}
@@ -161,7 +149,7 @@ function initDiffHeaderPopup() {
161149

162150
// Will be called when the show more (files) button has been pressed
163151
function onShowMoreFiles() {
164-
// FIXME: here the init calls are incomplete: at least it misses dropdown & initCompReactionSelector
152+
// FIXME: here the init calls are incomplete: at least it misses dropdown & initCompReactionSelector & initRepoDiffFileViewToggle
165153
initRepoIssueContentHistory();
166154
initViewedCheckboxListenerFor();
167155
countAndUpdateViewedFiles();
@@ -179,10 +167,11 @@ async function loadMoreFiles(btn: Element): Promise<boolean> {
179167
try {
180168
const response = await GET(url);
181169
const resp = await response.text();
182-
const $resp = $(resp);
170+
const respDoc = parseDom(resp, 'text/html');
171+
const respFileBoxes = respDoc.querySelector('#diff-file-boxes');
183172
// the response is a full HTML page, we need to extract the relevant contents:
184173
// * append the newly loaded file list items to the existing list
185-
$('#diff-incomplete').replaceWith($resp.find('#diff-file-boxes').children());
174+
document.querySelector('#diff-incomplete').replaceWith(...Array.from(respFileBoxes.children));
186175
onShowMoreFiles();
187176
return true;
188177
} catch (error) {
@@ -200,31 +189,27 @@ function initRepoDiffShowMore() {
200189
loadMoreFiles(el);
201190
});
202191

203-
$(document).on('click', 'a.diff-load-button', async (e) => {
192+
addDelegatedEventListener(document, 'click', 'a.diff-load-button', async (el, e) => {
204193
e.preventDefault();
205-
const $target = $(e.target);
206-
207-
if (e.target.classList.contains('disabled')) {
208-
return;
209-
}
210-
211-
e.target.classList.add('disabled');
194+
if (el.classList.contains('disabled')) return;
212195

213-
const url = $target.data('href');
196+
el.classList.add('disabled');
197+
const url = el.getAttribute('data-href');
214198

215199
try {
216200
const response = await GET(url);
217201
const resp = await response.text();
218-
219-
if (!resp) {
220-
return;
221-
}
222-
$target.parent().replaceWith($(resp).find('#diff-file-boxes .diff-file-body .file-body').children());
202+
const respDoc = parseDom(resp, 'text/html');
203+
const respFileBody = respDoc.querySelector('#diff-file-boxes .diff-file-body .file-body');
204+
el.parentElement.replaceWith(...Array.from(respFileBody.children));
205+
// FIXME: calling onShowMoreFiles is not quite right here.
206+
// But since onShowMoreFiles mixes "init diff box" and "init diff body" together,
207+
// so it still needs to call it to make the "ImageDiff" and something similar work.
223208
onShowMoreFiles();
224209
} catch (error) {
225210
console.error('Error:', error);
226211
} finally {
227-
e.target.classList.remove('disabled');
212+
el.classList.remove('disabled');
228213
}
229214
});
230215
}
@@ -262,8 +247,10 @@ function initRepoDiffHashChangeListener() {
262247
}
263248

264249
export function initRepoDiffView() {
265-
initRepoDiffConversationForm();
266-
if (!$('#diff-file-boxes').length) return;
250+
initRepoDiffConversationForm(); // such form appears on the "conversation" page and "diff" page
251+
252+
if (!document.querySelector('#diff-file-boxes')) return;
253+
initRepoDiffConversationNav(); // "previous" and "next" buttons only appear on "diff" page
267254
initDiffFileTree();
268255
initDiffCommitSelect();
269256
initRepoDiffShowMore();

web_src/js/features/repo-legacy.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {initUnicodeEscapeButton} from './repo-unicode-escape.ts';
99
import {initRepoCloneButtons} from './repo-common.ts';
1010
import {initCitationFileCopyContent} from './citation.ts';
1111
import {initCompLabelEdit} from './comp/LabelEdit.ts';
12-
import {initRepoDiffConversationNav} from './repo-diff.ts';
1312
import {initCompReactionSelector} from './comp/ReactionSelector.ts';
1413
import {initRepoSettings} from './repo-settings.ts';
1514
import {initRepoPullRequestMergeForm} from './repo-issue-pr-form.ts';
@@ -64,7 +63,6 @@ export function initRepository() {
6463
initRepoIssueWipToggle();
6564
initRepoIssueComments();
6665

67-
initRepoDiffConversationNav();
6866
initRepoIssueReferenceIssue();
6967

7068
initRepoIssueCommentDelete();

0 commit comments

Comments
 (0)