@ -74,11 +74,11 @@ export function initRepoCommentForm() {
}
if ( editMode === 'true' ) {
const $form = $ ( '# update_issueref_form') ;
const form = document . getElementById ( ' update_issueref_form') ;
const params = new URLSearchParams ( ) ;
params . append ( 'ref' , selectedValue ) ;
try {
await POST ( $form. attr ( 'action' ) , { data : params } ) ;
await POST ( form. getAttribute ( 'action' ) , { data : params } ) ;
window . location . reload ( ) ;
} catch ( error ) {
console . error ( error ) ;
@ -138,12 +138,12 @@ export function initRepoCommentForm() {
hasUpdateAction = $listMenu . data ( 'action' ) === 'update' ; // Update the var
const clickedItem = this ; // eslint-disable-line unicorn/no-this-assignment
const scope = $ ( this ) . attr ( 'data-scope' ) ;
const scope = this . getAttribute ( 'data-scope' ) ;
$ ( this ) . parent ( ) . find ( '.item' ) . each ( function ( ) {
if ( scope ) {
// Enable only clicked item for scoped labels
if ( $ ( this ) . attr ( 'data-scope' ) !== scope ) {
if ( this . getAttribute ( 'data-scope' ) !== scope ) {
return true ;
}
if ( this !== clickedItem && ! $ ( this ) . hasClass ( 'checked' ) ) {
@ -319,29 +319,32 @@ export function initRepoCommentForm() {
async function onEditContent ( event ) {
event . preventDefault ( ) ;
const $ segment = $ ( this ) . closest ( '.header' ) . next ( ) ;
const $editContentZone = $segment . find ( '.edit-content-zone' ) ;
const $renderContent = $segment . find ( '.render-content' ) ;
const $rawContent = $segment . find ( '.raw-content' ) ;
const segment = this . closest ( '.header' ) . next ElementSibling ;
const editContentZone = segment . querySelector ( '.edit-content-zone' ) ;
const renderContent = segment . querySelector ( '.render-content' ) ;
const rawContent = segment . querySelector ( '.raw-content' ) ;
let comboMarkdownEditor ;
const setupDropzone = async ( $dropzone ) => {
if ( ! $dropzone . length ) return null ;
/ * *
* @ param { HTMLElement } dropzone
* /
const setupDropzone = async ( dropzone ) => {
if ( ! dropzone ) return null ;
let disableRemovedfileEvent = false ; // when resetting the dropzone (removeAllFiles), disable the "removedfile" event
let fileUuidDict = { } ; // to record: if a comment has been saved, then the uploaded files won't be deleted from server when clicking the Remove in the dropzone
const dz = await createDropzone ( $ dropzone[ 0 ] , {
url : $dropzone. attr ( 'data-upload-url' ) ,
const dz = await createDropzone ( dropzone, {
url : dropzone. getAttribute ( 'data-upload-url' ) ,
headers : { 'X-Csrf-Token' : csrfToken } ,
maxFiles : $dropzone. attr ( 'data-max-file' ) ,
maxFilesize : $dropzone. attr ( 'data-max-size' ) ,
acceptedFiles : ( ['*/*' , '' ] . includes ( $dropzone. attr ( 'data-accepts' ) ) ) ? null : $dropzone . attr ( 'data-accepts' ) ,
maxFiles : dropzone. getAttribute ( 'data-max-file' ) ,
maxFilesize : dropzone. getAttribute ( 'data-max-size' ) ,
acceptedFiles : ['*/*' , '' ] . includes ( dropzone. getAttribute ( 'data-accepts' ) ) ? null : dropzone . getAttribute ( 'data-accepts' ) ,
addRemoveLinks : true ,
dictDefaultMessage : $dropzone. attr ( 'data-default-message' ) ,
dictInvalidFileType : $dropzone. attr ( 'data-invalid-input-type' ) ,
dictFileTooBig : $dropzone. attr ( 'data-file-too-big' ) ,
dictRemoveFile : $dropzone. attr ( 'data-remove-file' ) ,
dictDefaultMessage : dropzone. getAttribute ( 'data-default-message' ) ,
dictInvalidFileType : dropzone. getAttribute ( 'data-invalid-input-type' ) ,
dictFileTooBig : dropzone. getAttribute ( 'data-file-too-big' ) ,
dictRemoveFile : dropzone. getAttribute ( 'data-remove-file' ) ,
timeout : 0 ,
thumbnailMethod : 'contain' ,
thumbnailWidth : 480 ,
@ -350,46 +353,54 @@ async function onEditContent(event) {
this . on ( 'success' , ( file , data ) => {
file . uuid = data . uuid ;
fileUuidDict [ file . uuid ] = { submitted : false } ;
const $input = $ ( ` <input id=" ${ data . uuid } " name="files" type="hidden"> ` ) . val ( data . uuid ) ;
$dropzone . find ( '.files' ) . append ( $input ) ;
const input = document . createElement ( 'input' ) ;
input . id = data . uuid ;
input . name = 'files' ;
input . type = 'hidden' ;
input . value = data . uuid ;
dropzone . querySelector ( '.files' ) . insertAdjacentHTML ( 'beforeend' , input . outerHTML ) ;
} ) ;
this . on ( 'removedfile' , async ( file ) => {
if ( disableRemovedfileEvent ) return ;
$ ( ` # ${ file . uuid } ` ) . remove ( ) ;
if ( $dropzone. attr ( 'data-remove-url' ) && ! fileUuidDict [ file . uuid ] . submitted ) {
document . getElementById ( file . uuid ) ? . remove ( ) ;
if ( dropzone. getAttribute ( 'data-remove-url' ) && ! fileUuidDict [ file . uuid ] . submitted ) {
try {
await POST ( $dropzone. attr ( 'data-remove-url' ) , { data : new URLSearchParams ( { file : file . uuid } ) } ) ;
await POST ( dropzone. getAttribute ( 'data-remove-url' ) , { data : new URLSearchParams ( { file : file . uuid } ) } ) ;
} catch ( error ) {
console . error ( error ) ;
}
}
} ) ;
this . on ( 'submit' , ( ) => {
$ . each ( fileUuidDict , ( fileUuid ) => {
for ( const fileUuid of Object . keys ( fileUuidDict ) ) {
fileUuidDict [ fileUuid ] . submitted = true ;
} ) ;
}
} ) ;
this . on ( 'reload' , async ( ) => {
try {
const response = await GET ( $editContentZone. attr ( 'data-attachment-url' ) ) ;
const response = await GET ( editContentZone. getAttribute ( 'data-attachment-url' ) ) ;
const data = await response . json ( ) ;
// do not trigger the "removedfile" event, otherwise the attachments would be deleted from server
disableRemovedfileEvent = true ;
dz . removeAllFiles ( true ) ;
$dropzone. find ( '.files' ) . empty ( ) ;
dropzone. querySelector ( '.files' ) . innerHTML = '' ;
fileUuidDict = { } ;
disableRemovedfileEvent = false ;
for ( const attachment of data ) {
const imgSrc = ` ${ $dropzone. attr ( 'data-link-url' ) } / ${ attachment . uuid } ` ;
const imgSrc = ` ${ dropzone. getAttribute ( 'data-link-url' ) } / ${ attachment . uuid } ` ;
dz . emit ( 'addedfile' , attachment ) ;
dz . emit ( 'thumbnail' , attachment , imgSrc ) ;
dz . emit ( 'complete' , attachment ) ;
dz . files . push ( attachment ) ;
fileUuidDict [ attachment . uuid ] = { submitted : true } ;
$dropzone . find ( ` img[src=' ${ imgSrc } '] ` ) [ 0 ] . style . maxWidth = '100%' ;
const $input = $ ( ` <input id=" ${ attachment . uuid } " name="files" type="hidden"> ` ) . val ( attachment . uuid ) ;
$dropzone . find ( '.files' ) . append ( $input ) ;
dropzone . querySelector ( ` img[src=' ${ imgSrc } '] ` ) . style . maxWidth = '100%' ;
const input = document . createElement ( 'input' ) ;
input . id = attachment . uuid ;
input . name = 'files' ;
input . type = 'hidden' ;
input . value = attachment . uuid ;
dropzone . querySelector ( '.files' ) . insertAdjacentHTML ( 'beforeend' , input . outerHTML ) ;
}
} catch ( error ) {
console . error ( error ) ;
@ -402,44 +413,44 @@ async function onEditContent(event) {
} ;
const cancelAndReset = ( dz ) => {
showElem ( $ renderContent) ;
hideElem ( $ editContentZone) ;
showElem ( renderContent) ;
hideElem ( editContentZone) ;
if ( dz ) {
dz . emit ( 'reload' ) ;
}
} ;
const saveAndRefresh = async ( dz ) => {
showElem ( $ renderContent) ;
hideElem ( $ editContentZone) ;
showElem ( renderContent) ;
hideElem ( editContentZone) ;
try {
const params = new URLSearchParams ( {
content : comboMarkdownEditor . value ( ) ,
context : $editContentZone. attr ( 'data-context' ) ,
context : editContentZone. getAttribute ( 'data-context' ) ,
} ) ;
for ( const file of dz . files ) params . append ( 'files[]' , file . uuid ) ;
const response = await POST ( $editContentZone. attr ( 'data-update-url' ) , { data : params } ) ;
const response = await POST ( editContentZone. getAttribute ( 'data-update-url' ) , { data : params } ) ;
const data = await response . json ( ) ;
if ( ! data . content ) {
$renderContent. html ( $ ( '#no-content' ) . html ( ) ) ;
$rawContent. text ( '' ) ;
renderContent. innerHTML = document . getElementById ( 'no-content' ) . innerHTML ;
rawContent. textContent = '' ;
} else {
$renderContent. html ( data . content ) ;
$rawContent. text ( comboMarkdownEditor . value ( ) ) ;
const $refIssues = $renderContent . find ( 'p .ref-issue' ) ;
attachRefIssueContextPopup ( $ refIssues) ;
renderContent. innerHTML = data . content ;
rawContent. textContent = comboMarkdownEditor . value ( ) ;
const refIssues = renderContent . querySelectorAll ( 'p .ref-issue' ) ;
attachRefIssueContextPopup ( refIssues) ;
}
const $ content = $ segment;
if ( ! $content. find ( '.dropzone-attachments' ) . length ) {
const content = segment;
if ( ! content. querySelector ( '.dropzone-attachments' ) ) {
if ( data . attachments !== '' ) {
$ content[ 0 ] . insertAdjacentHTML ( 'beforeend' , data . attachments ) ;
content. insertAdjacentHTML ( 'beforeend' , data . attachments ) ;
}
} else if ( data . attachments === '' ) {
$content. find ( '.dropzone-attachments' ) . remove ( ) ;
content. querySelector ( '.dropzone-attachments' ) . remove ( ) ;
} else {
$content. find ( '.dropzone-attachments' ) [ 0 ] . outerHTML = data . attachments ;
content. querySelector ( '.dropzone-attachments' ) . outerHTML = data . attachments ;
}
if ( dz ) {
dz . emit ( 'submit' ) ;
@ -452,29 +463,29 @@ async function onEditContent(event) {
}
} ;
if ( ! $editContentZone. html ( ) ) {
$editContentZone. html ( $ ( '#issue-comment-editor-template' ) . html ( ) ) ;
comboMarkdownEditor = await initComboMarkdownEditor ( $editContentZone. find ( '.combo-markdown-editor' ) ) ;
if ( ! editContentZone. innerHTML ) {
editContentZone. innerHTML = document . getElementById ( 'issue-comment-editor-template' ) . innerHTML ;
comboMarkdownEditor = await initComboMarkdownEditor ( editContentZone. querySelector ( '.combo-markdown-editor' ) ) ;
const $dropzone = $editContentZone . find ( '.dropzone' ) ;
const dz = await setupDropzone ( $ dropzone) ;
$editContentZone. find ( '.cancel.button' ) . on ( 'click' , ( e ) => {
const dropzone = editContentZone . querySelector ( '.dropzone' ) ;
const dz = await setupDropzone ( dropzone) ;
editContentZone. querySelector ( '.cancel.button' ) . addEventListener ( 'click' , ( e ) => {
e . preventDefault ( ) ;
cancelAndReset ( dz ) ;
} ) ;
$editContentZone. find ( '.save.button' ) . on ( 'click' , ( e ) => {
editContentZone. querySelector ( '.save.button' ) . addEventListener ( 'click' , ( e ) => {
e . preventDefault ( ) ;
saveAndRefresh ( dz ) ;
} ) ;
} else {
comboMarkdownEditor = getComboMarkdownEditor ( $editContentZone. find ( '.combo-markdown-editor' ) ) ;
comboMarkdownEditor = getComboMarkdownEditor ( editContentZone. querySelector ( '.combo-markdown-editor' ) ) ;
}
// Show write/preview tab and copy raw content as needed
showElem ( $ editContentZone) ;
hideElem ( $ renderContent) ;
showElem ( editContentZone) ;
hideElem ( renderContent) ;
if ( ! comboMarkdownEditor . value ( ) ) {
comboMarkdownEditor . value ( $rawContent. text ( ) ) ;
comboMarkdownEditor . value ( rawContent. textContent ) ;
}
comboMarkdownEditor . focus ( ) ;
}