1
- import { ref , toRefs , onUnmounted , watch } from 'vue' ;
1
+ import { ref , toRefs , onUnmounted } from 'vue' ;
2
2
import type { SetupContext , Ref } from 'vue' ;
3
3
import { useCodeReviewLineSelection } from './use-code-review-line-selection' ;
4
- import type { LineSide , CodeReviewProps } from '../code-review-types' ;
4
+ import type { LineSide , CodeReviewProps , ICheckedLineDetails } from '../code-review-types' ;
5
5
import { useNamespace } from '../../../shared/hooks/use-namespace' ;
6
6
import {
7
7
notEmptyNode ,
@@ -14,28 +14,18 @@ import {
14
14
export function useCodeReviewComment ( reviewContentRef : Ref < HTMLElement > , props : CodeReviewProps , ctx : SetupContext ) {
15
15
const { outputFormat, allowComment, allowChecked } = toRefs ( props ) ;
16
16
const ns = useNamespace ( 'code-review' ) ;
17
- const { onMousedown } = useCodeReviewLineSelection ( reviewContentRef , props , afterMouseup ) ;
17
+ const { onMousedown, updateLineNumberMap, getCheckedLineDetails, clearCommentClass, updateCheckedLine } = useCodeReviewLineSelection (
18
+ reviewContentRef ,
19
+ props ,
20
+ afterMouseup
21
+ ) ;
18
22
const commentLeft = ref ( - 100 ) ;
19
23
const commentTop = ref ( - 100 ) ;
20
24
let currentLeftLineNumber = - 1 ;
21
25
let currentRightLineNumber = - 1 ;
26
+ let currentPosition : 'left' | 'right' ;
22
27
let lastLineNumberContainer : HTMLElement | null ;
23
- let checkedLineNumberContainer : Array < Element > = [ ] ;
24
- let currentLeftLineNumbers : Array < number > = [ ] ;
25
- let currentRightLineNumbers : Array < number > = [ ] ;
26
- let checkedLineCodeString : Array < string > | Record < string , Array < string > > = { } ;
27
- let allTrNodes : NodeListOf < Element > = [ ] ;
28
- let afterCheckLinesEmitData : Record < string , any > ;
29
- watch (
30
- ( ) => outputFormat . value ,
31
- ( ) => {
32
- // 如果出现单栏双栏切换则需要重置选中
33
- checkedLineNumberContainer = [ ] ;
34
- currentLeftLineNumbers = [ ] ;
35
- currentRightLineNumbers = [ ] ;
36
- checkedLineCodeString = [ ] ;
37
- }
38
- ) ;
28
+
39
29
const resetLeftTop = ( ) => {
40
30
commentLeft . value = - 100 ;
41
31
commentTop . value = - 100 ;
@@ -85,6 +75,8 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
85
75
commentLeft . value = left ;
86
76
commentTop . value = top ;
87
77
currentLeftLineNumber = parseInt ( leftLineNumberContainer . innerText ) ;
78
+ currentRightLineNumber = parseInt ( rightLineNumberContainer . innerText || '-1' ) ;
79
+ currentPosition = 'left' ;
88
80
} else {
89
81
resetLeftTop ( ) ;
90
82
}
@@ -98,7 +90,9 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
98
90
const { top, left } = rightLineNumberContainer . getBoundingClientRect ( ) ;
99
91
commentLeft . value = left ;
100
92
commentTop . value = top ;
93
+ currentLeftLineNumber = parseInt ( leftLineNumberContainer . innerText || '-1' ) ;
101
94
currentRightLineNumber = parseInt ( rightLineNumberContainer . innerText ) ;
95
+ currentPosition = 'right' ;
102
96
} else {
103
97
resetLeftTop ( ) ;
104
98
}
@@ -117,150 +111,27 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
117
111
resetLeftTop ( ) ;
118
112
}
119
113
} ;
120
- // 获取一些公共类和判断
121
- const getCommonClassAndJudge = ( ) => {
122
- const checkedLine = [ currentLeftLineNumbers , currentRightLineNumbers ] ;
123
- return {
124
- linenumberDom : allTrNodes ,
125
- checkedLine,
126
- } ;
127
- } ;
128
- // 之前每次都先移出所有选中的方法过于浪费性能,增加具体dom节点选中方法(防重复添加)
129
- const addCommentCheckedClass = ( Dom : Element ) => {
130
- ! Dom . classList . contains ( 'comment-checked' ) && Dom . classList . add ( 'comment-checked' ) ;
131
- } ;
132
- // 单栏
133
- function getSingleCheckedLineCode ( shouldRenderClass : boolean ) {
134
- const { linenumberDom, checkedLine } = getCommonClassAndJudge ( ) ;
135
- const checkedCodeContent = [ ] ;
136
- for ( let i = 0 ; i < linenumberDom . length ; i ++ ) {
137
- const lineNumberDomLeft = linenumberDom [ i ] . children [ 0 ] ;
138
- const lineNumberDomRight = linenumberDom [ i ] . children [ 1 ] ;
139
- if ( lineNumberDomLeft || lineNumberDomRight ) {
140
- const codeLineNumberLeft = parseInt ( ( lineNumberDomLeft as HTMLElement ) ?. innerText ) ;
141
- const codeLineNumberRight = parseInt ( ( lineNumberDomRight as HTMLElement ) ?. innerText ) ;
142
- // 因为存在左边或者右边为空的num所以两边都要循环,但是同一个dom已经过就不需要再赋予
143
- if ( checkedLine [ 0 ] . includes ( codeLineNumberLeft ) || checkedLine [ 1 ] . includes ( codeLineNumberRight ) ) {
144
- checkedLineNumberContainer . push ( linenumberDom [ i ] ) ;
145
- // 两个节点之间可能间隔文本节点
146
- const codeNode = linenumberDom [ i ] . nextElementSibling as HTMLElement ;
147
- checkedCodeContent . push ( codeNode ?. innerText ) ;
148
- if ( shouldRenderClass ) {
149
- addCommentCheckedClass ( linenumberDom [ i ] ) ;
150
- addCommentCheckedClass ( codeNode ) ;
151
- }
152
- }
153
- }
154
- }
155
- checkedLineCodeString = checkedCodeContent ;
156
- }
157
- // 双栏
158
- function getDoubleCheckedLineCode ( shouldRenderClass : boolean ) {
159
- const { linenumberDom, checkedLine } = getCommonClassAndJudge ( ) ;
160
- const checkedCodeContentLeft = [ ] ;
161
- const checkedCodeContentRight = [ ] ;
162
-
163
- function checkedFunc ( Dom : Element ) {
164
- checkedLineNumberContainer . push ( Dom ) ;
165
- const codeNode = Dom . nextElementSibling as HTMLElement ;
166
- if ( shouldRenderClass ) {
167
- addCommentCheckedClass ( Dom ) ;
168
- addCommentCheckedClass ( codeNode ) ;
169
- }
170
- return codeNode ?. innerText ;
171
- }
172
114
173
- for ( let i = 0 ; i < linenumberDom . length ; i ++ ) {
174
- // 左右双栏一起遍历
175
- const codeLineNumber = parseInt ( linenumberDom [ i ] ?. innerHTML ) ;
176
- if ( linenumberDom [ i ] . classList . contains ( 'd-code-left' ) && checkedLine [ 0 ] . includes ( codeLineNumber ) ) {
177
- const lineNumText = checkedFunc ( linenumberDom [ i ] ) ;
178
- checkedCodeContentLeft . push ( lineNumText ) ;
179
- continue ;
180
- }
181
- if ( linenumberDom [ i ] . classList . contains ( 'd-code-right' ) && checkedLine [ 1 ] . includes ( codeLineNumber ) ) {
182
- const lineNumText = checkedFunc ( linenumberDom [ i ] ) ;
183
- checkedCodeContentRight . push ( lineNumText ) ;
184
- }
185
- }
186
- checkedLineCodeString = { leftCode : checkedCodeContentLeft , rightCode : checkedCodeContentRight } ;
187
- }
188
- function getCheckedLineCode ( shouldRenderClass : boolean ) {
189
- if ( props . outputFormat === 'line-by-line' ) {
190
- return getSingleCheckedLineCode ( shouldRenderClass ) ;
191
- }
192
- getDoubleCheckedLineCode ( shouldRenderClass ) ;
193
- }
194
- function updateLineNumbers ( { lefts, rights } : { lefts : number [ ] ; rights : number [ ] } ) {
195
- currentLeftLineNumbers = lefts ;
196
- currentRightLineNumbers = rights ;
197
- getCheckedLineCode ( false ) ;
198
- afterCheckLinesEmitData = {
199
- left : currentLeftLineNumber ,
200
- right : currentRightLineNumber ,
201
- details : {
202
- lefts : currentLeftLineNumbers ,
203
- rights : currentRightLineNumbers ,
204
- codes : checkedLineCodeString ,
205
- } ,
206
- } ;
207
- }
208
- const updateCheckedLineClass = ( ) => {
209
- const lineClassName = props . outputFormat === 'line-by-line' ? '.d2h-code-linenumber' : '.d2h-code-side-linenumber' ;
210
- allTrNodes = reviewContentRef . value . querySelectorAll ( lineClassName ) ;
211
- getCheckedLineCode ( true ) ;
212
- } ;
213
- // 还原样式
214
- const resetCommentClass = ( ) => {
215
- for ( let i = 0 ; i < checkedLineNumberContainer . length ; i ++ ) {
216
- checkedLineNumberContainer [ i ] . classList . remove ( 'comment-checked' ) ;
217
- const codeNode = checkedLineNumberContainer [ i ] . nextElementSibling ;
218
- ( codeNode as HTMLElement ) ?. classList . remove ( 'comment-checked' ) ;
219
- }
220
- checkedLineNumberContainer = [ ] ;
221
- } ;
222
115
// 点击
223
116
const commentClick = ( ) => {
224
- interface recordType {
225
- left : number ;
226
- right : number ;
227
- details ?: {
228
- lefts : Array < number > ;
229
- rights : Array < number > ;
230
- codes : Record < string , Array < string > > | Record < string , Array < number > > ;
231
- } ;
232
- }
233
- let obj : recordType = { left : currentLeftLineNumber , right : currentRightLineNumber } ;
234
- if ( ( currentLeftLineNumbers . length >= 1 || currentRightLineNumbers . length >= 1 ) && allowChecked . value ) {
235
- // 选中模式
236
- const maxCurrentLeftLineNumber = currentLeftLineNumbers [ currentLeftLineNumbers . length - 1 ] ;
237
- const maxCurrentRightLineNumber = currentRightLineNumbers [ currentRightLineNumbers . length - 1 ] ;
238
- if ( maxCurrentLeftLineNumber === currentLeftLineNumber || maxCurrentRightLineNumber === currentRightLineNumber ) {
239
- // 点击添加评论图标触发的事件
240
- obj = {
241
- left : currentLeftLineNumber ,
242
- right : currentRightLineNumber ,
243
- details : {
244
- lefts : currentLeftLineNumbers ,
245
- rights : currentRightLineNumbers ,
246
- codes : checkedLineCodeString ,
247
- } ,
248
- } ;
117
+ let obj = { left : currentLeftLineNumber , right : currentRightLineNumber , position : currentPosition } ;
118
+ const checkedLineDetails = getCheckedLineDetails ( ) ;
119
+ // 多行选中
120
+ if ( checkedLineDetails && allowChecked . value ) {
121
+ const { lefts, rights } = checkedLineDetails ;
122
+ const maxCheckedLeftLineNumber = lefts [ lefts . length - 1 ] ;
123
+ const maxCheckedRightLineNumber = rights [ rights . length - 1 ] ;
124
+ if ( maxCheckedLeftLineNumber === currentLeftLineNumber || maxCheckedRightLineNumber === currentRightLineNumber ) {
125
+ obj . details = checkedLineDetails ;
249
126
} else {
250
- currentLeftLineNumbers = [ ] ;
251
- currentRightLineNumbers = [ ] ;
252
- resetCommentClass ( ) ;
127
+ clearCommentClass ( ) ;
253
128
}
254
129
}
255
130
// 点击添加评论图标触发的事件
256
131
ctx . emit ( 'addComment' , obj ) ;
257
132
} ;
258
- function afterCheckLines ( ) {
259
- ctx . emit ( 'afterCheckLines' , afterCheckLinesEmitData ) ;
260
- }
261
- function afterMouseup ( lineNumbers : { lefts : number [ ] ; rights : number [ ] } ) {
262
- updateLineNumbers ( lineNumbers ) ;
263
- afterCheckLines ( ) ;
133
+ function afterMouseup ( details : ICheckedLineDetails ) {
134
+ ctx . emit ( 'afterCheckLines' , { left : currentLeftLineNumber , right : currentRightLineNumber , position : currentPosition , details } ) ;
264
135
}
265
136
// 图标或者单行的点击
266
137
const onCommentIconClick = ( e : Event ) => {
@@ -317,16 +188,7 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
317
188
} ;
318
189
319
190
const clearCheckedLines = ( ) => {
320
- currentLeftLineNumbers = [ ] ;
321
- currentRightLineNumbers = [ ] ;
322
- checkedLineCodeString = [ ] ;
323
- resetCommentClass ( ) ;
324
- } ;
325
-
326
- const handleMouseDown = ( e : MouseEvent ) => {
327
- const lineClassName = props . outputFormat === 'line-by-line' ? '.d2h-code-linenumber' : '.d2h-code-side-linenumber' ;
328
- allTrNodes = reviewContentRef . value . querySelectorAll ( lineClassName ) ;
329
- onMousedown ( e ) ;
191
+ clearCommentClass ( ) ;
330
192
} ;
331
193
332
194
const mouseEvent : Record < string , ( e : MouseEvent ) => void > = { } ;
@@ -335,7 +197,7 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
335
197
mouseEvent . onMouseleave = onMouseleave ;
336
198
}
337
199
if ( props . allowChecked ) {
338
- mouseEvent . onMousedown = handleMouseDown ;
200
+ mouseEvent . onMousedown = onMousedown ;
339
201
}
340
202
341
203
window . addEventListener ( 'scroll' , resetLeftTop ) ;
@@ -348,11 +210,12 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
348
210
commentLeft,
349
211
commentTop,
350
212
mouseEvent,
351
- updateCheckedLineClass,
352
213
clearCheckedLines,
353
214
onCommentMouseLeave,
354
215
onCommentIconClick,
355
216
insertComment,
356
217
removeComment,
218
+ updateLineNumberMap,
219
+ updateCheckedLine,
357
220
} ;
358
221
}
0 commit comments