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 , updateLineNumbers , afterCheckLines ) ;
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,168 +111,27 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
117
111
resetLeftTop ( ) ;
118
112
}
119
113
} ;
120
- // 获代码行 取值方法
121
- const getLineNumbers = ( currentNumber : number , currentNumbers : Array < number > , moveDirection : 'up' | 'down' ) => {
122
- if ( currentNumber === - 1 ) {
123
- // 当前行没数据不代表之前选中的没数据,此时返回原来的
124
- return currentNumbers ;
125
- }
126
- if ( currentNumbers . length === 0 ) {
127
- return [ currentNumber ] ;
128
- }
129
- const numbers = [ ...currentNumbers ] ;
130
- let max = Math . max ( ...numbers ) ;
131
- let min = Math . min ( ...numbers ) ;
132
- if ( moveDirection === 'down' ) {
133
- max = currentNumber ;
134
- }
135
- if ( moveDirection === 'up' ) {
136
- min = currentNumber ;
137
- }
138
- return Array . from ( { length : max - min + 1 } , ( _ , i ) => i + min ) ;
139
- } ;
140
- // 获取一些公共类和判断
141
- const getCommonClassAndJudge = ( ) => {
142
- const checkedLine = [ currentLeftLineNumbers , currentRightLineNumbers ] ;
143
- return {
144
- linenumberDom : allTrNodes ,
145
- checkedLine,
146
- } ;
147
- } ;
148
- // 之前每次都先移出所有选中的方法过于浪费性能,增加具体dom节点选中方法(防重复添加)
149
- const addCommentCheckedClass = ( Dom : Element ) => {
150
- ! Dom . classList . contains ( 'comment-checked' ) && Dom . classList . add ( 'comment-checked' ) ;
151
- } ;
152
- // 单栏
153
- function getSingleCheckedLineCode ( shouldRenderClass : boolean ) {
154
- const { linenumberDom, checkedLine } = getCommonClassAndJudge ( ) ;
155
- const checkedCodeContent = [ ] ;
156
- for ( let i = 0 ; i < linenumberDom . length ; i ++ ) {
157
- const lineNumberDomLeft = linenumberDom [ i ] . children [ 0 ] ;
158
- const lineNumberDomRight = linenumberDom [ i ] . children [ 1 ] ;
159
- if ( lineNumberDomLeft || lineNumberDomRight ) {
160
- const codeLineNumberLeft = parseInt ( ( lineNumberDomLeft as HTMLElement ) ?. innerText ) ;
161
- const codeLineNumberRight = parseInt ( ( lineNumberDomRight as HTMLElement ) ?. innerText ) ;
162
- // 因为存在左边或者右边为空的num所以两边都要循环,但是同一个dom已经过就不需要再赋予
163
- if ( checkedLine [ 0 ] . includes ( codeLineNumberLeft ) || checkedLine [ 1 ] . includes ( codeLineNumberRight ) ) {
164
- checkedLineNumberContainer . push ( linenumberDom [ i ] ) ;
165
- // 两个节点之间可能间隔文本节点
166
- const codeNode = linenumberDom [ i ] . nextElementSibling as HTMLElement ;
167
- checkedCodeContent . push ( codeNode ?. innerText ) ;
168
- if ( shouldRenderClass ) {
169
- addCommentCheckedClass ( linenumberDom [ i ] ) ;
170
- addCommentCheckedClass ( codeNode ) ;
171
- }
172
- }
173
- }
174
- }
175
- checkedLineCodeString = checkedCodeContent ;
176
- }
177
- // 双栏
178
- function getDoubleCheckedLineCode ( shouldRenderClass : boolean ) {
179
- const { linenumberDom, checkedLine } = getCommonClassAndJudge ( ) ;
180
- const checkedCodeContentLeft = [ ] ;
181
- const checkedCodeContentRight = [ ] ;
182
114
183
- function checkedFunc ( Dom : Element ) {
184
- checkedLineNumberContainer . push ( Dom ) ;
185
- const codeNode = Dom . nextElementSibling as HTMLElement ;
186
- if ( shouldRenderClass ) {
187
- addCommentCheckedClass ( Dom ) ;
188
- addCommentCheckedClass ( codeNode ) ;
189
- }
190
- return codeNode ?. innerText ;
191
- }
192
-
193
- for ( let i = 0 ; i < linenumberDom . length ; i ++ ) {
194
- // 左右双栏一起遍历
195
- const codeLineNumber = parseInt ( linenumberDom [ i ] ?. innerHTML ) ;
196
- if ( linenumberDom [ i ] . classList . contains ( 'd-code-left' ) && checkedLine [ 0 ] . includes ( codeLineNumber ) ) {
197
- const lineNumText = checkedFunc ( linenumberDom [ i ] ) ;
198
- checkedCodeContentLeft . push ( lineNumText ) ;
199
- continue ;
200
- }
201
- if ( linenumberDom [ i ] . classList . contains ( 'd-code-right' ) && checkedLine [ 1 ] . includes ( codeLineNumber ) ) {
202
- const lineNumText = checkedFunc ( linenumberDom [ i ] ) ;
203
- checkedCodeContentRight . push ( lineNumText ) ;
204
- }
205
- }
206
- checkedLineCodeString = { leftCode : checkedCodeContentLeft , rightCode : checkedCodeContentRight } ;
207
- }
208
- function getCheckedLineCode ( shouldRenderClass : boolean ) {
209
- if ( props . outputFormat === 'line-by-line' ) {
210
- return getSingleCheckedLineCode ( shouldRenderClass ) ;
211
- }
212
- getDoubleCheckedLineCode ( shouldRenderClass ) ;
213
- }
214
- function updateLineNumbers ( moveDirection : 'up' | 'down' ) {
215
- currentLeftLineNumbers =
216
- currentLeftLineNumber === - 1 ? currentLeftLineNumbers : getLineNumbers ( currentLeftLineNumber , currentLeftLineNumbers , moveDirection ) ;
217
- currentRightLineNumbers =
218
- currentRightLineNumber === - 1
219
- ? currentRightLineNumbers
220
- : getLineNumbers ( currentRightLineNumber , currentRightLineNumbers , moveDirection ) ;
221
- getCheckedLineCode ( false ) ;
222
- afterCheckLinesEmitData = {
223
- left : currentLeftLineNumber ,
224
- right : currentRightLineNumber ,
225
- details : {
226
- lefts : currentLeftLineNumbers ,
227
- rights : currentRightLineNumbers ,
228
- codes : checkedLineCodeString ,
229
- } ,
230
- } ;
231
- }
232
- const updateCheckedLineClass = ( ) => {
233
- getCheckedLineCode ( true ) ;
234
- } ;
235
- // 还原样式
236
- const resetCommentClass = ( ) => {
237
- for ( let i = 0 ; i < checkedLineNumberContainer . length ; i ++ ) {
238
- checkedLineNumberContainer [ i ] . classList . remove ( 'comment-checked' ) ;
239
- const codeNode = checkedLineNumberContainer [ i ] . nextElementSibling ;
240
- ( codeNode as HTMLElement ) ?. classList . remove ( 'comment-checked' ) ;
241
- }
242
- checkedLineNumberContainer = [ ] ;
243
- } ;
244
115
// 点击
245
116
const commentClick = ( ) => {
246
- interface recordType {
247
- left : number ;
248
- right : number ;
249
- details ?: {
250
- lefts : Array < number > ;
251
- rights : Array < number > ;
252
- codes : Record < string , Array < string > > | Record < string , Array < number > > ;
253
- } ;
254
- }
255
- let obj : recordType = { left : currentLeftLineNumber , right : currentRightLineNumber } ;
256
- if ( ( currentLeftLineNumbers . length >= 1 || currentRightLineNumbers . length >= 1 ) && allowChecked . value ) {
257
- // 选中模式
258
- const maxCurrentLeftLineNumber = currentLeftLineNumbers [ currentLeftLineNumbers . length - 1 ] ;
259
- const maxCurrentRightLineNumber = currentRightLineNumbers [ currentRightLineNumbers . length - 1 ] ;
260
- if ( maxCurrentLeftLineNumber === currentLeftLineNumber || maxCurrentRightLineNumber === currentRightLineNumber ) {
261
- // 点击添加评论图标触发的事件
262
- obj = {
263
- left : currentLeftLineNumber ,
264
- right : currentRightLineNumber ,
265
- details : {
266
- lefts : currentLeftLineNumbers ,
267
- rights : currentRightLineNumbers ,
268
- codes : checkedLineCodeString ,
269
- } ,
270
- } ;
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 ;
271
126
} else {
272
- currentLeftLineNumbers = [ ] ;
273
- currentRightLineNumbers = [ ] ;
274
- resetCommentClass ( ) ;
127
+ clearCommentClass ( ) ;
275
128
}
276
129
}
277
130
// 点击添加评论图标触发的事件
278
131
ctx . emit ( 'addComment' , obj ) ;
279
132
} ;
280
- function afterCheckLines ( ) {
281
- ctx . emit ( 'afterCheckLines' , afterCheckLinesEmitData ) ;
133
+ function afterMouseup ( details : ICheckedLineDetails ) {
134
+ ctx . emit ( 'afterCheckLines' , { left : currentLeftLineNumber , right : currentRightLineNumber , position : currentPosition , details } ) ;
282
135
}
283
136
// 图标或者单行的点击
284
137
const onCommentIconClick = ( e : Event ) => {
@@ -335,16 +188,7 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
335
188
} ;
336
189
337
190
const clearCheckedLines = ( ) => {
338
- currentLeftLineNumbers = [ ] ;
339
- currentRightLineNumbers = [ ] ;
340
- checkedLineCodeString = [ ] ;
341
- resetCommentClass ( ) ;
342
- } ;
343
-
344
- const handleMouseDown = ( e : MouseEvent ) => {
345
- const lineClassName = props . outputFormat === 'line-by-line' ? '.d2h-code-linenumber' : '.d2h-code-side-linenumber' ;
346
- allTrNodes = reviewContentRef . value . querySelectorAll ( lineClassName ) ;
347
- onMousedown ( e ) ;
191
+ clearCommentClass ( ) ;
348
192
} ;
349
193
350
194
const mouseEvent : Record < string , ( e : MouseEvent ) => void > = { } ;
@@ -353,7 +197,7 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
353
197
mouseEvent . onMouseleave = onMouseleave ;
354
198
}
355
199
if ( props . allowChecked ) {
356
- mouseEvent . onMousedown = handleMouseDown ;
200
+ mouseEvent . onMousedown = onMousedown ;
357
201
}
358
202
359
203
window . addEventListener ( 'scroll' , resetLeftTop ) ;
@@ -366,11 +210,12 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
366
210
commentLeft,
367
211
commentTop,
368
212
mouseEvent,
369
- updateCheckedLineClass,
370
213
clearCheckedLines,
371
214
onCommentMouseLeave,
372
215
onCommentIconClick,
373
216
insertComment,
374
217
removeComment,
218
+ updateLineNumberMap,
219
+ updateCheckedLine,
375
220
} ;
376
- }
221
+ }
0 commit comments