11import { ref , toRefs , onUnmounted , watch } from 'vue' ;
22import type { SetupContext , Ref } from 'vue' ;
3+ import { useCodeReviewLineSelection } from './use-code-review-line-selection' ;
34import type { LineSide , CodeReviewProps } from '../code-review-types' ;
45import { useNamespace } from '../../../shared/hooks/use-namespace' ;
56import {
@@ -13,23 +14,26 @@ import {
1314export function useCodeReviewComment ( reviewContentRef : Ref < HTMLElement > , props : CodeReviewProps , ctx : SetupContext ) {
1415 const { outputFormat, allowComment, allowChecked } = toRefs ( props ) ;
1516 const ns = useNamespace ( 'code-review' ) ;
17+ const { onMousedown } = useCodeReviewLineSelection ( reviewContentRef , props , updateLineNumbers , updateLineNumbers ) ;
1618 const commentLeft = ref ( - 100 ) ;
1719 const commentTop = ref ( - 100 ) ;
1820 let currentLeftLineNumber = - 1 ;
1921 let currentRightLineNumber = - 1 ;
2022 let lastLineNumberContainer : HTMLElement | null ;
2123 let checkedLineNumberContainer : Array < Element > = [ ] ;
22- let isShift = false ;
2324 let currentLeftLineNumbers : Array < number > = [ ] ;
2425 let currentRightLineNumbers : Array < number > = [ ] ;
2526 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+ ) ;
3337 const resetLeftTop = ( ) => {
3438 commentLeft . value = - 100 ;
3539 commentTop . value = - 100 ;
@@ -111,105 +115,83 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
111115 resetLeftTop ( ) ;
112116 }
113117 } ;
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- } ;
140118 // 获代码行 取值方法
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+ // 当前行没数据不代表之前选中的没数据,此时返回原来的
143122 return currentNumbers ;
144123 }
145124 if ( currentNumbers . length === 0 ) {
146125 return [ currentNumber ] ;
147126 }
148127 const numbers = [ ...currentNumbers ] ;
149128 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 ) {
152134 max = currentNumber ;
153135 }
154136 return Array . from ( { length : max - min + 1 } , ( _ , i ) => i + min ) ;
155137 } ;
156138 // 获取一些公共类和判断
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' ;
159141 const linenumberDom = reviewContentRef . value . querySelectorAll ( lineClassName ) ;
160142 const checkedLine = [ currentLeftLineNumbers , currentRightLineNumbers ] ;
161143 return {
162144 linenumberDom,
163- checkedLine
145+ checkedLine,
164146 } ;
165147 } ;
166148 // 之前每次都先移出所有选中的方法过于浪费性能,增加具体dom节点选中方法(防重复添加)
167149 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' ) ;
169151 } ;
170- // 选中(单栏)
171- const addCommentClassSingle = ( side : string ) => {
172- const { linenumberDom, checkedLine } = getCommonClassAndJudge ( side ) ;
152+ // 单栏
153+ function getSingleCheckedLineCode ( shouldRenderClass : boolean ) {
154+ const { linenumberDom, checkedLine } = getCommonClassAndJudge ( ) ;
173155 const checkedCodeContent = [ ] ;
174- // resetCommentClass();
175156 for ( let i = 0 ; i < linenumberDom . length ; i ++ ) {
176157 const lineNumberDomLeft = linenumberDom [ i ] . children [ 0 ] ;
177158 const lineNumberDomRight = linenumberDom [ i ] . children [ 1 ] ;
178159 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 ) ;
181162 // 因为存在左边或者右边为空的num所以两边都要循环,但是同一个dom已经过就不需要再赋予
182163 if ( checkedLine [ 0 ] . includes ( codeLineNumberLeft ) || checkedLine [ 1 ] . includes ( codeLineNumberRight ) ) {
183164 checkedLineNumberContainer . push ( linenumberDom [ i ] ) ;
184165 // 两个节点之间可能间隔文本节点
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+ }
191172 }
192173 }
193174 }
194175 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 ( ) ;
199180 const checkedCodeContentLeft = [ ] ;
200181 const checkedCodeContentRight = [ ] ;
201182
202183 function checkedFunc ( Dom : Element ) {
203184 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 ;
210191 }
211192
212- for ( let i = 0 ; i < linenumberDom . length ; i ++ ) { // 左右双栏一起遍历
193+ for ( let i = 0 ; i < linenumberDom . length ; i ++ ) {
194+ // 左右双栏一起遍历
213195 const codeLineNumber = parseInt ( linenumberDom [ i ] ?. innerHTML ) ;
214196 if ( linenumberDom [ i ] . classList . contains ( 'd-code-left' ) && checkedLine [ 0 ] . includes ( codeLineNumber ) ) {
215197 const lineNumText = checkedFunc ( linenumberDom [ i ] ) ;
@@ -222,37 +204,34 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
222204 }
223205 }
224206 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 ) ;
230211 }
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 ) ;
232223 } ;
233224 // 还原样式
234225 const resetCommentClass = ( ) => {
235226 for ( let i = 0 ; i < checkedLineNumberContainer . length ; i ++ ) {
236227 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 ;
240229 ( codeNode as HTMLElement ) ?. classList . remove ( 'comment-checked' ) ;
241230 }
242231 checkedLineNumberContainer = [ ] ;
243232 } ;
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- } ;
254233 // 点击
255- const commentClick = ( e : Event ) => {
234+ const commentClick = ( ) => {
256235 interface recordType {
257236 left : number ;
258237 right : number ;
@@ -263,15 +242,22 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
263242 } ;
264243 }
265244 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+ // 选中模式
267247 const maxCurrentLeftLineNumber = currentLeftLineNumbers [ currentLeftLineNumbers . length - 1 ] ;
268248 const maxCurrentRightLineNumber = currentRightLineNumbers [ currentRightLineNumbers . length - 1 ] ;
269249 if ( maxCurrentLeftLineNumber === currentLeftLineNumber || maxCurrentRightLineNumber === currentRightLineNumber ) {
270250 // 点击添加评论图标触发的事件
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 {
275261 currentLeftLineNumbers = [ ] ;
276262 currentRightLineNumbers = [ ] ;
277263 resetCommentClass ( ) ;
@@ -282,7 +268,8 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
282268 } ;
283269 // 图标或者单行的点击
284270 const onCommentIconClick = ( e : Event ) => {
285- if ( e ) { // 根据时间反回的dom判断是否点击中的制定区域
271+ if ( e ) {
272+ // 根据时间反回的dom判断是否点击中的制定区域
286273 const composedPath = e . composedPath ( ) as HTMLElement [ ] ;
287274 const lineNumberBox = composedPath . find (
288275 ( item ) => item . classList ?. contains ( 'comment-icon-hover' ) || item . classList ?. contains ( 'comment-icon' )
@@ -291,12 +278,7 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
291278 return ;
292279 }
293280 }
294- // 按住shift键选中
295- if ( isShift && allowChecked . value ) {
296- commentShiftClick ( e ) ;
297- return ;
298- }
299- commentClick ( e ) ;
281+ commentClick ( ) ;
300282 } ;
301283 const insertComment = ( lineNumber : number , lineSide : LineSide , commentDom : HTMLElement ) => {
302284 if ( outputFormat . value === 'line-by-line' ) {
@@ -345,7 +327,14 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
345327 resetCommentClass ( ) ;
346328 } ;
347329
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+ }
349338
350339 window . addEventListener ( 'scroll' , resetLeftTop ) ;
351340
@@ -357,14 +346,10 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
357346 commentLeft,
358347 commentTop,
359348 mouseEvent,
360- // currentLeftLineNumbers,
361- // currentRightLineNumbers,
362349 updateCheckedLineClass,
363350 clearCheckedLines,
364351 onCommentMouseLeave,
365352 onCommentIconClick,
366- onCommentKeyDown,
367- unCommentKeyDown,
368353 insertComment,
369354 removeComment,
370355 } ;
0 commit comments