1- import { ref , toRefs , onUnmounted , watch } from 'vue' ;
1+ import { ref , toRefs , onUnmounted } from 'vue' ;
22import type { SetupContext , Ref } from 'vue' ;
33import { 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' ;
55import { useNamespace } from '../../../shared/hooks/use-namespace' ;
66import {
77 notEmptyNode ,
@@ -14,28 +14,18 @@ import {
1414export function useCodeReviewComment ( reviewContentRef : Ref < HTMLElement > , props : CodeReviewProps , ctx : SetupContext ) {
1515 const { outputFormat, allowComment, allowChecked } = toRefs ( props ) ;
1616 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+ ) ;
1822 const commentLeft = ref ( - 100 ) ;
1923 const commentTop = ref ( - 100 ) ;
2024 let currentLeftLineNumber = - 1 ;
2125 let currentRightLineNumber = - 1 ;
26+ let currentPosition : 'left' | 'right' ;
2227 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+
3929 const resetLeftTop = ( ) => {
4030 commentLeft . value = - 100 ;
4131 commentTop . value = - 100 ;
@@ -85,6 +75,8 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
8575 commentLeft . value = left ;
8676 commentTop . value = top ;
8777 currentLeftLineNumber = parseInt ( leftLineNumberContainer . innerText ) ;
78+ currentRightLineNumber = parseInt ( rightLineNumberContainer . innerText || '-1' ) ;
79+ currentPosition = 'left' ;
8880 } else {
8981 resetLeftTop ( ) ;
9082 }
@@ -98,7 +90,9 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
9890 const { top, left } = rightLineNumberContainer . getBoundingClientRect ( ) ;
9991 commentLeft . value = left ;
10092 commentTop . value = top ;
93+ currentLeftLineNumber = parseInt ( leftLineNumberContainer . innerText || '-1' ) ;
10194 currentRightLineNumber = parseInt ( rightLineNumberContainer . innerText ) ;
95+ currentPosition = 'right' ;
10296 } else {
10397 resetLeftTop ( ) ;
10498 }
@@ -117,168 +111,27 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
117111 resetLeftTop ( ) ;
118112 }
119113 } ;
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 = [ ] ;
182114
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- } ;
244115 // 点击
245116 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 ;
271126 } else {
272- currentLeftLineNumbers = [ ] ;
273- currentRightLineNumbers = [ ] ;
274- resetCommentClass ( ) ;
127+ clearCommentClass ( ) ;
275128 }
276129 }
277130 // 点击添加评论图标触发的事件
278131 ctx . emit ( 'addComment' , obj ) ;
279132 } ;
280- function afterCheckLines ( ) {
281- ctx . emit ( 'afterCheckLines' , afterCheckLinesEmitData ) ;
133+ function afterMouseup ( details : ICheckedLineDetails ) {
134+ ctx . emit ( 'afterCheckLines' , { left : currentLeftLineNumber , right : currentRightLineNumber , position : currentPosition , details } ) ;
282135 }
283136 // 图标或者单行的点击
284137 const onCommentIconClick = ( e : Event ) => {
@@ -335,16 +188,7 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
335188 } ;
336189
337190 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 ( ) ;
348192 } ;
349193
350194 const mouseEvent : Record < string , ( e : MouseEvent ) => void > = { } ;
@@ -353,7 +197,7 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
353197 mouseEvent . onMouseleave = onMouseleave ;
354198 }
355199 if ( props . allowChecked ) {
356- mouseEvent . onMousedown = handleMouseDown ;
200+ mouseEvent . onMousedown = onMousedown ;
357201 }
358202
359203 window . addEventListener ( 'scroll' , resetLeftTop ) ;
@@ -366,11 +210,12 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
366210 commentLeft,
367211 commentTop,
368212 mouseEvent,
369- updateCheckedLineClass,
370213 clearCheckedLines,
371214 onCommentMouseLeave,
372215 onCommentIconClick,
373216 insertComment,
374217 removeComment,
218+ updateLineNumberMap,
219+ updateCheckedLine,
375220 } ;
376- }
221+ }
0 commit comments