1
- import $ from 'jquery' ;
2
1
import { handleReply } from './repo-issue.ts' ;
3
2
import { getComboMarkdownEditor , initComboMarkdownEditor , ComboMarkdownEditor } from './comp/ComboMarkdownEditor.ts' ;
4
3
import { POST } from '../modules/fetch.ts' ;
@@ -7,11 +6,14 @@ import {hideElem, showElem} from '../utils/dom.ts';
7
6
import { attachRefIssueContextPopup } from './contextpopup.ts' ;
8
7
import { initCommentContent , initMarkupContent } from '../markup/content.ts' ;
9
8
import { triggerUploadStateChanged } from './comp/EditorUpload.ts' ;
9
+ import { convertHtmlToMarkdown } from '../markup/html2markdown.ts' ;
10
10
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 ;
13
14
14
- const segment = this . closest ( '.header' ) . nextElementSibling ;
15
+ e . preventDefault ( ) ;
16
+ const segment = clickTarget . closest ( '.header' ) . nextElementSibling ;
15
17
const editContentZone = segment . querySelector ( '.edit-content-zone' ) ;
16
18
const renderContent = segment . querySelector ( '.render-content' ) ;
17
19
const rawContent = segment . querySelector ( '.raw-content' ) ;
@@ -100,33 +102,53 @@ async function onEditContent(event) {
100
102
triggerUploadStateChanged ( comboMarkdownEditor . container ) ;
101
103
}
102
104
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 '' ;
106
110
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
+ }
113
118
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
131
153
} ) ;
132
154
}
0 commit comments