1- import $ from 'jquery' ;
21import { initCompReactionSelector } from './comp/ReactionSelector.ts' ;
32import { initRepoIssueContentHistory } from './repo-issue-content.ts' ;
43import { initDiffFileTree } from './repo-diff-filetree.ts' ;
@@ -7,35 +6,28 @@ import {validateTextareaNonEmpty} from './comp/ComboMarkdownEditor.ts';
76import { initViewedCheckboxListenerFor , countAndUpdateViewedFiles , initExpandAndCollapseFilesButton } from './pull-view-file.ts' ;
87import { initImageDiff } from './imagediff.ts' ;
98import { 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' ;
1910import { POST , GET } from '../modules/fetch.ts' ;
2011import { fomanticQuery } from '../modules/fomantic/base.ts' ;
2112import { createTippy } from '../modules/tippy.ts' ;
2213import { invertFileFolding } from './file-fold.ts' ;
14+ import { parseDom } from '../utils.ts' ;
2315
2416const { i18n} = window . config ;
2517
2618function 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
4133function 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
163151function 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
264249export 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 ( ) ;
0 commit comments