1
1
import { ref , toRefs , onUnmounted , watch } from 'vue' ;
2
2
import type { SetupContext , Ref } from 'vue' ;
3
+ import { useCodeReviewLineSelection } from './use-code-review-line-selection' ;
3
4
import type { LineSide , CodeReviewProps } from '../code-review-types' ;
4
5
import { useNamespace } from '../../../shared/hooks/use-namespace' ;
5
6
import {
@@ -13,23 +14,26 @@ import {
13
14
export function useCodeReviewComment ( reviewContentRef : Ref < HTMLElement > , props : CodeReviewProps , ctx : SetupContext ) {
14
15
const { outputFormat, allowComment, allowChecked } = toRefs ( props ) ;
15
16
const ns = useNamespace ( 'code-review' ) ;
17
+ const { onMousedown } = useCodeReviewLineSelection ( reviewContentRef , props , updateLineNumbers , updateLineNumbers ) ;
16
18
const commentLeft = ref ( - 100 ) ;
17
19
const commentTop = ref ( - 100 ) ;
18
20
let currentLeftLineNumber = - 1 ;
19
21
let currentRightLineNumber = - 1 ;
20
22
let lastLineNumberContainer : HTMLElement | null ;
21
23
let checkedLineNumberContainer : Array < Element > = [ ] ;
22
- let isShift = false ;
23
24
let currentLeftLineNumbers : Array < number > = [ ] ;
24
25
let currentRightLineNumbers : Array < number > = [ ] ;
25
26
let checkedLineCodeString : Array < string > | Record < string , Array < string > > = { } ;
26
- watch ( ( ) => outputFormat . value , ( ) => {
27
- // 如果出现单栏双栏切换则需要重置选中
28
- checkedLineNumberContainer = [ ] ;
29
- currentLeftLineNumbers = [ ] ;
30
- currentRightLineNumbers = [ ] ;
31
- checkedLineCodeString = [ ] ;
32
- } ) ;
27
+ watch (
28
+ ( ) => outputFormat . value ,
29
+ ( ) => {
30
+ // 如果出现单栏双栏切换则需要重置选中
31
+ checkedLineNumberContainer = [ ] ;
32
+ currentLeftLineNumbers = [ ] ;
33
+ currentRightLineNumbers = [ ] ;
34
+ checkedLineCodeString = [ ] ;
35
+ }
36
+ ) ;
33
37
const resetLeftTop = ( ) => {
34
38
commentLeft . value = - 100 ;
35
39
commentTop . value = - 100 ;
@@ -111,105 +115,83 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
111
115
resetLeftTop ( ) ;
112
116
}
113
117
} ;
114
- function commentKeyDown ( e : any ) {
115
- // keyCode已经被废弃了 用e.key代替 或者e.code代替
116
- switch ( e . key ) {
117
- case 'Shift' :
118
- isShift = true ;
119
- break ;
120
- }
121
- }
122
- function commentKeyUp ( e : any ) {
123
- e . preventDefault ( ) ;
124
- switch ( e . key ) {
125
- case 'Shift' :
126
- isShift = false ;
127
- break ;
128
- }
129
- }
130
- // 销毁键盘事件
131
- const unCommentKeyDown = ( ) => {
132
- document . removeEventListener ( 'keydown' , commentKeyDown ) ;
133
- document . removeEventListener ( 'keyup' , commentKeyUp ) ;
134
- } ;
135
- // 键盘事件
136
- const onCommentKeyDown = ( ) => {
137
- document . addEventListener ( 'keydown' , commentKeyDown ) ;
138
- document . addEventListener ( 'keyup' , commentKeyUp ) ;
139
- } ;
140
118
// 获代码行 取值方法
141
- const getLineNumbers = ( currentNumber : number , currentNumbers : Array < number > , e : Event ) => {
142
- if ( currentNumber === - 1 ) { // 当前行没数据不代表之前选中的没数据,此时返回原来的
119
+ const getLineNumbers = ( currentNumber : number , currentNumbers : Array < number > ) => {
120
+ if ( currentNumber === - 1 ) {
121
+ // 当前行没数据不代表之前选中的没数据,此时返回原来的
143
122
return currentNumbers ;
144
123
}
145
124
if ( currentNumbers . length === 0 ) {
146
125
return [ currentNumber ] ;
147
126
}
148
127
const numbers = [ ...currentNumbers ] ;
149
128
let max = Math . max ( ...numbers ) ;
150
- const min = Math . min ( ...numbers ) ;
151
- if ( currentNumber > max ) { // 限制规则只能从小选到大。
129
+ let min = Math . min ( ...numbers ) ;
130
+ if ( currentNumber < min ) {
131
+ min = currentNumber ;
132
+ }
133
+ if ( currentNumber > max ) {
152
134
max = currentNumber ;
153
135
}
154
136
return Array . from ( { length : max - min + 1 } , ( _ , i ) => i + min ) ;
155
137
} ;
156
138
// 获取一些公共类和判断
157
- const getCommonClassAndJudge = ( side : string ) => {
158
- const lineClassName = side === 'line-by-line' ? '.d2h-code-linenumber' : '.d2h-code-side-linenumber' ;
139
+ const getCommonClassAndJudge = ( ) => {
140
+ const lineClassName = props . outputFormat === 'line-by-line' ? '.d2h-code-linenumber' : '.d2h-code-side-linenumber' ;
159
141
const linenumberDom = reviewContentRef . value . querySelectorAll ( lineClassName ) ;
160
142
const checkedLine = [ currentLeftLineNumbers , currentRightLineNumbers ] ;
161
143
return {
162
144
linenumberDom,
163
- checkedLine
145
+ checkedLine,
164
146
} ;
165
147
} ;
166
148
// 之前每次都先移出所有选中的方法过于浪费性能,增加具体dom节点选中方法(防重复添加)
167
149
const addCommentCheckedClass = ( Dom : Element ) => {
168
- ! Dom . classList . contains ( 'comment-checked' ) && Dom . classList . add ( 'comment-checked' ) ;
150
+ ! Dom . classList . contains ( 'comment-checked' ) && Dom . classList . add ( 'comment-checked' ) ;
169
151
} ;
170
- // 选中(单栏)
171
- const addCommentClassSingle = ( side : string ) => {
172
- const { linenumberDom, checkedLine } = getCommonClassAndJudge ( side ) ;
152
+ // 单栏
153
+ function getSingleCheckedLineCode ( shouldRenderClass : boolean ) {
154
+ const { linenumberDom, checkedLine } = getCommonClassAndJudge ( ) ;
173
155
const checkedCodeContent = [ ] ;
174
- // resetCommentClass();
175
156
for ( let i = 0 ; i < linenumberDom . length ; i ++ ) {
176
157
const lineNumberDomLeft = linenumberDom [ i ] . children [ 0 ] ;
177
158
const lineNumberDomRight = linenumberDom [ i ] . children [ 1 ] ;
178
159
if ( lineNumberDomLeft || lineNumberDomRight ) {
179
- const codeLineNumberLeft = parseInt ( ( lineNumberDomLeft as HTMLElement ) ?. innerText ) ;
180
- const codeLineNumberRight = parseInt ( ( lineNumberDomRight as HTMLElement ) ?. innerText ) ;
160
+ const codeLineNumberLeft = parseInt ( ( lineNumberDomLeft as HTMLElement ) ?. innerText ) ;
161
+ const codeLineNumberRight = parseInt ( ( lineNumberDomRight as HTMLElement ) ?. innerText ) ;
181
162
// 因为存在左边或者右边为空的num所以两边都要循环,但是同一个dom已经过就不需要再赋予
182
163
if ( checkedLine [ 0 ] . includes ( codeLineNumberLeft ) || checkedLine [ 1 ] . includes ( codeLineNumberRight ) ) {
183
164
checkedLineNumberContainer . push ( linenumberDom [ i ] ) ;
184
165
// 两个节点之间可能间隔文本节点
185
- const codeNode = ( linenumberDom [ i ] . nextSibling as HTMLElement ) . nodeName === '#text'
186
- ? ( linenumberDom [ i ] . nextSibling as HTMLElement ) . nextSibling
187
- : linenumberDom [ i ] . nextSibling ;
188
- checkedCodeContent . push ( ( codeNode as HTMLElement ) ?. innerText ) ;
189
- addCommentCheckedClass ( linenumberDom [ i ] ) ;
190
- addCommentCheckedClass ( codeNode as HTMLElement ) ;
166
+ const codeNode = linenumberDom [ i ] . nextElementSibling as HTMLElement ;
167
+ checkedCodeContent . push ( codeNode ?. innerText ) ;
168
+ if ( shouldRenderClass ) {
169
+ addCommentCheckedClass ( linenumberDom [ i ] ) ;
170
+ addCommentCheckedClass ( codeNode ) ;
171
+ }
191
172
}
192
173
}
193
174
}
194
175
checkedLineCodeString = checkedCodeContent ;
195
- } ;
196
- // 选中(双栏)
197
- const addCommentClassDouble = ( side : string ) => {
198
- const { linenumberDom, checkedLine } = getCommonClassAndJudge ( side ) ;
176
+ }
177
+ // 双栏
178
+ function getDoubleCheckedLineCode ( shouldRenderClass : boolean ) {
179
+ const { linenumberDom, checkedLine } = getCommonClassAndJudge ( ) ;
199
180
const checkedCodeContentLeft = [ ] ;
200
181
const checkedCodeContentRight = [ ] ;
201
182
202
183
function checkedFunc ( Dom : Element ) {
203
184
checkedLineNumberContainer . push ( Dom ) ;
204
- const codeNode = ( Dom . nextSibling as HTMLElement ) . nodeName === '#text'
205
- ? ( Dom . nextSibling as HTMLElement ) . nextSibling
206
- : Dom . nextSibling ;
207
- addCommentCheckedClass ( Dom ) ;
208
- addCommentCheckedClass ( codeNode as HTMLElement ) ;
209
- return ( codeNode as HTMLElement ) ?. innerText ;
185
+ const codeNode = Dom . nextElementSibling as HTMLElement ;
186
+ if ( shouldRenderClass ) {
187
+ addCommentCheckedClass ( Dom ) ;
188
+ addCommentCheckedClass ( codeNode ) ;
189
+ }
190
+ return codeNode ?. innerText ;
210
191
}
211
192
212
- for ( let i = 0 ; i < linenumberDom . length ; i ++ ) { // 左右双栏一起遍历
193
+ for ( let i = 0 ; i < linenumberDom . length ; i ++ ) {
194
+ // 左右双栏一起遍历
213
195
const codeLineNumber = parseInt ( linenumberDom [ i ] ?. innerHTML ) ;
214
196
if ( linenumberDom [ i ] . classList . contains ( 'd-code-left' ) && checkedLine [ 0 ] . includes ( codeLineNumber ) ) {
215
197
const lineNumText = checkedFunc ( linenumberDom [ i ] ) ;
@@ -222,37 +204,34 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
222
204
}
223
205
}
224
206
checkedLineCodeString = { leftCode : checkedCodeContentLeft , rightCode : checkedCodeContentRight } ;
225
- } ;
226
- const updateCheckedLineClass = ( ) => {
227
- if ( outputFormat . value === 'line-by-line' ) {
228
- addCommentClassSingle ( outputFormat . value ) ;
229
- return ;
207
+ }
208
+ function getCheckedLineCode ( shouldRenderClass : boolean ) {
209
+ if ( props . outputFormat === 'line-by-line' ) {
210
+ return getSingleCheckedLineCode ( shouldRenderClass ) ;
230
211
}
231
- addCommentClassDouble ( outputFormat . value ) ;
212
+ getDoubleCheckedLineCode ( shouldRenderClass ) ;
213
+ }
214
+ function updateLineNumbers ( ) {
215
+ currentLeftLineNumbers =
216
+ currentLeftLineNumber === - 1 ? currentLeftLineNumbers : getLineNumbers ( currentLeftLineNumber , currentLeftLineNumbers ) ;
217
+ currentRightLineNumbers =
218
+ currentRightLineNumber === - 1 ? currentRightLineNumbers : getLineNumbers ( currentRightLineNumber , currentRightLineNumbers ) ;
219
+ getCheckedLineCode ( false ) ;
220
+ }
221
+ const updateCheckedLineClass = ( ) => {
222
+ getCheckedLineCode ( true ) ;
232
223
} ;
233
224
// 还原样式
234
225
const resetCommentClass = ( ) => {
235
226
for ( let i = 0 ; i < checkedLineNumberContainer . length ; i ++ ) {
236
227
checkedLineNumberContainer [ i ] . classList . remove ( 'comment-checked' ) ;
237
- const codeNode = ( checkedLineNumberContainer [ i ] . nextSibling as HTMLElement ) . nodeName === '#text'
238
- ? ( checkedLineNumberContainer [ i ] . nextSibling as HTMLElement ) . nextSibling
239
- : checkedLineNumberContainer [ i ] . nextSibling ;
228
+ const codeNode = checkedLineNumberContainer [ i ] . nextElementSibling ;
240
229
( codeNode as HTMLElement ) ?. classList . remove ( 'comment-checked' ) ;
241
230
}
242
231
checkedLineNumberContainer = [ ] ;
243
232
} ;
244
- // 按住shift键点击
245
- const commentShiftClick = ( e : Event ) => {
246
- currentLeftLineNumbers = currentLeftLineNumber === - 1
247
- ? currentLeftLineNumbers
248
- : getLineNumbers ( currentLeftLineNumber , currentLeftLineNumbers , e ) ;
249
- currentRightLineNumbers = currentRightLineNumber === - 1
250
- ? currentRightLineNumbers
251
- : getLineNumbers ( currentRightLineNumber , currentRightLineNumbers , e ) ;
252
- updateCheckedLineClass ( ) ;
253
- } ;
254
233
// 点击
255
- const commentClick = ( e : Event ) => {
234
+ const commentClick = ( ) => {
256
235
interface recordType {
257
236
left : number ;
258
237
right : number ;
@@ -263,15 +242,22 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
263
242
} ;
264
243
}
265
244
let obj : recordType = { left : currentLeftLineNumber , right : currentRightLineNumber } ;
266
- if ( currentLeftLineNumbers . length >= 1 || currentRightLineNumbers . length >= 1 && allowChecked . value ) { // 选中模式
245
+ if ( ( currentLeftLineNumbers . length >= 1 || currentRightLineNumbers . length >= 1 ) && allowChecked . value ) {
246
+ // 选中模式
267
247
const maxCurrentLeftLineNumber = currentLeftLineNumbers [ currentLeftLineNumbers . length - 1 ] ;
268
248
const maxCurrentRightLineNumber = currentRightLineNumbers [ currentRightLineNumbers . length - 1 ] ;
269
249
if ( maxCurrentLeftLineNumber === currentLeftLineNumber || maxCurrentRightLineNumber === currentRightLineNumber ) {
270
250
// 点击添加评论图标触发的事件
271
- obj = { left : currentLeftLineNumber , right : currentRightLineNumber , details : {
272
- lefts : currentLeftLineNumbers , rights : currentRightLineNumbers , codes : checkedLineCodeString
273
- } } ;
274
- } else {
251
+ obj = {
252
+ left : currentLeftLineNumber ,
253
+ right : currentRightLineNumber ,
254
+ details : {
255
+ lefts : currentLeftLineNumbers ,
256
+ rights : currentRightLineNumbers ,
257
+ codes : checkedLineCodeString ,
258
+ } ,
259
+ } ;
260
+ } else {
275
261
currentLeftLineNumbers = [ ] ;
276
262
currentRightLineNumbers = [ ] ;
277
263
resetCommentClass ( ) ;
@@ -282,7 +268,8 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
282
268
} ;
283
269
// 图标或者单行的点击
284
270
const onCommentIconClick = ( e : Event ) => {
285
- if ( e ) { // 根据时间反回的dom判断是否点击中的制定区域
271
+ if ( e ) {
272
+ // 根据时间反回的dom判断是否点击中的制定区域
286
273
const composedPath = e . composedPath ( ) as HTMLElement [ ] ;
287
274
const lineNumberBox = composedPath . find (
288
275
( item ) => item . classList ?. contains ( 'comment-icon-hover' ) || item . classList ?. contains ( 'comment-icon' )
@@ -291,12 +278,7 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
291
278
return ;
292
279
}
293
280
}
294
- // 按住shift键选中
295
- if ( isShift && allowChecked . value ) {
296
- commentShiftClick ( e ) ;
297
- return ;
298
- }
299
- commentClick ( e ) ;
281
+ commentClick ( ) ;
300
282
} ;
301
283
const insertComment = ( lineNumber : number , lineSide : LineSide , commentDom : HTMLElement ) => {
302
284
if ( outputFormat . value === 'line-by-line' ) {
@@ -345,7 +327,14 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
345
327
resetCommentClass ( ) ;
346
328
} ;
347
329
348
- const mouseEvent = allowComment . value ? { onMousemove : onMouseMove , onMouseleave : onMouseleave } : { } ;
330
+ const mouseEvent : Record < string , ( e : MouseEvent ) => void > = { } ;
331
+ if ( allowComment . value ) {
332
+ mouseEvent . onMousemove = onMouseMove ;
333
+ mouseEvent . onMouseleave = onMouseleave ;
334
+ }
335
+ if ( props . allowChecked ) {
336
+ mouseEvent . onMousedown = onMousedown ;
337
+ }
349
338
350
339
window . addEventListener ( 'scroll' , resetLeftTop ) ;
351
340
@@ -357,14 +346,10 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
357
346
commentLeft,
358
347
commentTop,
359
348
mouseEvent,
360
- // currentLeftLineNumbers,
361
- // currentRightLineNumbers,
362
349
updateCheckedLineClass,
363
350
clearCheckedLines,
364
351
onCommentMouseLeave,
365
352
onCommentIconClick,
366
- onCommentKeyDown,
367
- unCommentKeyDown,
368
353
insertComment,
369
354
removeComment,
370
355
} ;
0 commit comments