1- import $ from 'jquery' ;
21import { initCompReactionSelector } from './comp/ReactionSelector.ts' ;
32import { initRepoIssueContentHistory } from './repo-issue-content.ts' ;
43import { initDiffFileTree } from './repo-diff-filetree.ts' ;
@@ -14,7 +13,7 @@ import {
1413 showElem ,
1514 animateOnce ,
1615 addDelegatedEventListener ,
17- createElementFromHTML ,
16+ createElementFromHTML , queryElems ,
1817} from '../utils/dom.ts' ;
1918import { POST , GET } from '../modules/fetch.ts' ;
2019import { fomanticQuery } from '../modules/fomantic/base.ts' ;
@@ -24,18 +23,18 @@ import {invertFileFolding} from './file-fold.ts';
2423const { i18n} = window . config ;
2524
2625function 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' ) ;
26+ // switch between "rendered" and "source", for image and CSV files
27+ // FIXME: this event listener is not correctly added to "load more files"
28+ queryElems ( document , '.file-view-toggle' , ( btn ) => btn . addEventListener ( 'click' , ( ) => {
29+ queryElemSiblings ( btn , '.file-view-toggle' , ( el ) => el . classList . remove ( 'active' ) ) ;
30+ btn . classList . add ( 'active' ) ;
3231
33- const target = document . querySelector ( this . getAttribute ( 'data-toggle-selector' ) ) ;
34- if ( ! target ) return ;
32+ const target = document . querySelector ( btn . getAttribute ( 'data-toggle-selector' ) ) ;
33+ if ( ! target ) throw new Error ( 'Target element not found' ) ;
3534
3635 hideElem ( queryElemSiblings ( target ) ) ;
3736 showElem ( target ) ;
38- } ) ;
37+ } ) ) ;
3938}
4039
4140function initRepoDiffConversationForm ( ) {
@@ -103,22 +102,23 @@ function initRepoDiffConversationForm() {
103102 }
104103 } ) ;
105104
106- $ ( document ) . on ( 'click' , '.resolve-conversation' , async function ( e ) {
105+ addDelegatedEventListener ( document , 'click' , '.resolve-conversation' , async ( el , e ) => {
107106 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') ;
107+ const comment_id = el . getAttribute ( 'data- comment-id') ;
108+ const origin = el . getAttribute ( 'data- origin') ;
109+ const action = el . getAttribute ( 'data- action') ;
110+ const url = el . getAttribute ( 'data- update-url') ;
112111
113112 try {
114113 const response = await POST ( url , { data : new URLSearchParams ( { origin, action, comment_id} ) } ) ;
115114 const data = await response . text ( ) ;
116115
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 ] ) ;
116+ const elConversationHolder = el . closest ( '.conversation-holder' ) ;
117+ if ( elConversationHolder ) {
118+ const elNewConversation = createElementFromHTML ( data ) ;
119+ elConversationHolder . replaceWith ( elNewConversation ) ;
120+ queryElems ( elConversationHolder , '.ui.dropdown:not(.custom)' , ( el ) => fomanticQuery ( el ) . dropdown ( ) ) ;
121+ initCompReactionSelector ( elNewConversation ) ;
122122 } else {
123123 window . location . reload ( ) ;
124124 }
@@ -128,24 +128,19 @@ function initRepoDiffConversationForm() {
128128 } ) ;
129129}
130130
131- export function initRepoDiffConversationNav ( ) {
131+ function initRepoDiffConversationNav ( ) {
132132 // 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' ) ;
133+ addDelegatedEventListener ( document , 'click' , '.previous-conversation, .next-conversation' , ( el , e ) => {
134+ e . preventDefault ( ) ;
135+ const isPrevious = el . matches ( '.previous-conversation' ) ;
136+ const elCurConversation = el . closest ( '.comment-code-cloud' ) ;
137+ const elAllConversations = document . querySelectorAll ( '.comment-code-cloud:not(.tw-hidden)' ) ;
138+ const index = Array . from ( elAllConversations ) . indexOf ( elCurConversation ) ;
139+ const previousIndex = index > 0 ? index - 1 : elAllConversations . length - 1 ;
140+ const nextIndex = index < elAllConversations . length - 1 ? index + 1 : 0 ;
141+ const navIndex = isPrevious ? previousIndex : nextIndex ;
142+ const elNavConversation = elAllConversations [ navIndex ] ;
143+ const anchor = elNavConversation . querySelector ( '.comment' ) . id ;
149144 window . location . href = `#${ anchor } ` ;
150145 } ) ;
151146}
@@ -161,7 +156,7 @@ function initDiffHeaderPopup() {
161156
162157// Will be called when the show more (files) button has been pressed
163158function onShowMoreFiles ( ) {
164- // FIXME: here the init calls are incomplete: at least it misses dropdown & initCompReactionSelector
159+ // FIXME: here the init calls are incomplete: at least it misses dropdown & initCompReactionSelector & initRepoDiffFileViewToggle
165160 initRepoIssueContentHistory ( ) ;
166161 initViewedCheckboxListenerFor ( ) ;
167162 countAndUpdateViewedFiles ( ) ;
@@ -179,10 +174,11 @@ async function loadMoreFiles(btn: Element): Promise<boolean> {
179174 try {
180175 const response = await GET ( url ) ;
181176 const resp = await response . text ( ) ;
182- const $resp = $ ( resp ) ;
177+ const respDoc = new DOMParser ( ) . parseFromString ( resp , 'text/html' ) ;
178+ const respFileBoxes = respDoc . querySelector ( '#diff-file-boxes' ) ;
183179 // the response is a full HTML page, we need to extract the relevant contents:
184180 // * append the newly loaded file list items to the existing list
185- $ ( '#diff-incomplete' ) . replaceWith ( $resp . find ( '#diff-file-boxes' ) . children ( ) ) ;
181+ document . querySelector ( '#diff-incomplete' ) . replaceWith ( ... Array . from ( respFileBoxes . children ) ) ;
186182 onShowMoreFiles ( ) ;
187183 return true ;
188184 } catch ( error ) {
@@ -200,31 +196,27 @@ function initRepoDiffShowMore() {
200196 loadMoreFiles ( el ) ;
201197 } ) ;
202198
203- $ ( document ) . on ( 'click' , 'a.diff-load-button' , async ( e ) => {
199+ addDelegatedEventListener ( document , 'click' , 'a.diff-load-button' , async ( el , e ) => {
204200 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' ) ;
201+ if ( el . classList . contains ( 'disabled' ) ) return ;
212202
213- const url = $target . data ( 'href' ) ;
203+ el . classList . add ( 'disabled' ) ;
204+ const url = el . getAttribute ( 'data-href' ) ;
214205
215206 try {
216207 const response = await GET ( url ) ;
217208 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 ( ) ) ;
209+ const respDoc = new DOMParser ( ) . parseFromString ( resp , 'text/html' ) ;
210+ const respFileBody = respDoc . querySelector ( '#diff-file-boxes .diff-file-body .file-body' ) ;
211+ el . parentElement . replaceWith ( ...Array . from ( respFileBody . children ) ) ;
212+ // FIXME: calling onShowMoreFiles is not quite right here.
213+ // But since onShowMoreFiles mixes "init diff box" and "init diff body" together,
214+ // so it still needs to call it to make the "ImageDiff" and something similar work.
223215 onShowMoreFiles ( ) ;
224216 } catch ( error ) {
225217 console . error ( 'Error:' , error ) ;
226218 } finally {
227- e . target . classList . remove ( 'disabled' ) ;
219+ el . classList . remove ( 'disabled' ) ;
228220 }
229221 } ) ;
230222}
@@ -262,8 +254,10 @@ function initRepoDiffHashChangeListener() {
262254}
263255
264256export function initRepoDiffView ( ) {
265- initRepoDiffConversationForm ( ) ;
266- if ( ! $ ( '#diff-file-boxes' ) . length ) return ;
257+ initRepoDiffConversationForm ( ) ; // such form appears on the "conversation" page and "diff" page
258+
259+ if ( ! document . querySelector ( '#diff-file-boxes' ) ) return ;
260+ initRepoDiffConversationNav ( ) ; // "previous" and "next" buttons only appear on "diff" page
267261 initDiffFileTree ( ) ;
268262 initDiffCommitSelect ( ) ;
269263 initRepoDiffShowMore ( ) ;
0 commit comments