1- import  $  from  'jquery' ; 
21import  { handleReply }  from  './repo-issue.ts' ; 
32import  { getComboMarkdownEditor ,  initComboMarkdownEditor ,  ComboMarkdownEditor }  from  './comp/ComboMarkdownEditor.ts' ; 
43import  { POST }  from  '../modules/fetch.ts' ; 
@@ -7,11 +6,14 @@ import {hideElem, showElem} from '../utils/dom.ts';
76import  { attachRefIssueContextPopup }  from  './contextpopup.ts' ; 
87import  { initCommentContent ,  initMarkupContent }  from  '../markup/content.ts' ; 
98import  { triggerUploadStateChanged }  from  './comp/EditorUpload.ts' ; 
9+ import  { convertHtmlToMarkdown }  from  '../markup/html2markdown.ts' ; 
1010
11- async  function  onEditContent ( event )  { 
12-   event . preventDefault ( ) ; 
11+ async  function  tryOnEditContent ( e )  { 
12+   const  clickTarget  =  e . target . closest ( '.edit-content' ) ; 
13+   if  ( ! clickTarget )  return ; 
1314
14-   const  segment  =  this . closest ( '.header' ) . nextElementSibling ; 
15+   e . preventDefault ( ) ; 
16+   const  segment  =  clickTarget . closest ( '.header' ) . nextElementSibling ; 
1517  const  editContentZone  =  segment . querySelector ( '.edit-content-zone' ) ; 
1618  const  renderContent  =  segment . querySelector ( '.render-content' ) ; 
1719  const  rawContent  =  segment . querySelector ( '.raw-content' ) ; 
@@ -100,33 +102,53 @@ async function onEditContent(event) {
100102  triggerUploadStateChanged ( comboMarkdownEditor . container ) ; 
101103} 
102104
103- export  function  initRepoIssueCommentEdit ( )  { 
104-   // Edit issue or comment content 
105-   $ ( document ) . on ( 'click' ,  '.edit-content' ,  onEditContent ) ; 
105+ function  extractSelectedMarkdown ( container : HTMLElement )  { 
106+   const  selection  =  window . getSelection ( ) ; 
107+   if  ( ! selection . rangeCount )  return  '' ; 
108+   const  range  =  selection . getRangeAt ( 0 ) ; 
109+   if  ( ! container . contains ( range . commonAncestorContainer ) )  return  '' ; 
106110
107-   // Quote reply 
108-   $ ( document ) . on ( 'click' ,  '.quote-reply' ,  async  function  ( event )  { 
109-     event . preventDefault ( ) ; 
110-     const  target  =  this . getAttribute ( 'data-target' ) ; 
111-     const  quote  =  document . querySelector ( `#${ target }  ` ) . textContent . replace ( / \n / g,  '\n> ' ) ; 
112-     const  content  =  `> ${ quote }  \n\n` ; 
111+   // todo: if commonAncestorContainer parent has "[data-markdown-original-content]" attribute, use the parent's markdown content 
112+   // otherwise, use the selected HTML content and respect all "[data-markdown-original-content]/[data-markdown-generated-content]" attributes 
113+   const  contents  =  selection . getRangeAt ( 0 ) . cloneContents ( ) ; 
114+   const  el  =  document . createElement ( 'div' ) ; 
115+   el . append ( contents ) ; 
116+   return  convertHtmlToMarkdown ( el ) ; 
117+ } 
113118
114-     let  editor ; 
115-     if  ( this . classList . contains ( 'quote-reply-diff' ) )  { 
116-       const  replyBtn  =  this . closest ( '.comment-code-cloud' ) . querySelector ( 'button.comment-form-reply' ) ; 
117-       editor  =  await  handleReply ( replyBtn ) ; 
118-     }  else  { 
119-       // for normal issue/comment page 
120-       editor  =  getComboMarkdownEditor ( $ ( '#comment-form .combo-markdown-editor' ) ) ; 
121-     } 
122-     if  ( editor )  { 
123-       if  ( editor . value ( ) )  { 
124-         editor . value ( `${ editor . value ( ) }  \n\n${ content }  ` ) ; 
125-       }  else  { 
126-         editor . value ( content ) ; 
127-       } 
128-       editor . focus ( ) ; 
129-       editor . moveCursorToEnd ( ) ; 
130-     } 
119+ async  function  tryOnQuoteReply ( e )  { 
120+   const  clickTarget  =  ( e . target  as  HTMLElement ) . closest ( '.quote-reply' ) ; 
121+   if  ( ! clickTarget )  return ; 
122+ 
123+   e . preventDefault ( ) ; 
124+   const  contentToQuoteId  =  clickTarget . getAttribute ( 'data-target' ) ; 
125+   const  targetRawToQuote  =  document . querySelector < HTMLElement > ( `#${ contentToQuoteId }  .raw-content` ) ; 
126+   const  targetMarkupToQuote  =  targetRawToQuote . parentElement . querySelector < HTMLElement > ( '.render-content.markup' ) ; 
127+   let  contentToQuote  =  extractSelectedMarkdown ( targetMarkupToQuote ) ; 
128+   if  ( ! contentToQuote )  contentToQuote  =  targetRawToQuote . textContent ; 
129+   const  quotedContent  =  `${ contentToQuote . replace ( / ^ / mg,  '> ' ) }  \n` ; 
130+ 
131+   let  editor ; 
132+   if  ( clickTarget . classList . contains ( 'quote-reply-diff' ) )  { 
133+     const  replyBtn  =  clickTarget . closest ( '.comment-code-cloud' ) . querySelector ( 'button.comment-form-reply' ) ; 
134+     editor  =  await  handleReply ( replyBtn ) ; 
135+   }  else  { 
136+     // for normal issue/comment page 
137+     editor  =  getComboMarkdownEditor ( document . querySelector ( '#comment-form .combo-markdown-editor' ) ) ; 
138+   } 
139+ 
140+   if  ( editor . value ( ) )  { 
141+     editor . value ( `${ editor . value ( ) }  \n\n${ quotedContent }  ` ) ; 
142+   }  else  { 
143+     editor . value ( quotedContent ) ; 
144+   } 
145+   editor . focus ( ) ; 
146+   editor . moveCursorToEnd ( ) ; 
147+ } 
148+ 
149+ export  function  initRepoIssueCommentEdit ( )  { 
150+   document . addEventListener ( 'click' ,  ( e )  =>  { 
151+     tryOnEditContent ( e ) ;  // Edit issue or comment content 
152+     tryOnQuoteReply ( e ) ;  // Quote reply to the comment editor 
131153  } ) ; 
132154} 
0 commit comments