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