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 , afterMouseup ) ;
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,150 +111,27 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
117111 resetLeftTop ( ) ;
118112 }
119113 } ;
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- }
172114
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- } ;
222115 // 点击
223116 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 ] ;
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 maxCurrentLeftLineNumber = lefts [ lefts . length - 1 ] ;
123+ const maxCurrentRightLineNumber = rights [ rights . length - 1 ] ;
238124 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- } ;
125+ obj . details = checkedLineDetails ;
249126 } else {
250- currentLeftLineNumbers = [ ] ;
251- currentRightLineNumbers = [ ] ;
252- resetCommentClass ( ) ;
127+ clearCommentClass ( ) ;
253128 }
254129 }
255130 // 点击添加评论图标触发的事件
256131 ctx . emit ( 'addComment' , obj ) ;
257132 } ;
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 } ) ;
264135 }
265136 // 图标或者单行的点击
266137 const onCommentIconClick = ( e : Event ) => {
@@ -317,16 +188,7 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
317188 } ;
318189
319190 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 ( ) ;
330192 } ;
331193
332194 const mouseEvent : Record < string , ( e : MouseEvent ) => void > = { } ;
@@ -335,7 +197,7 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
335197 mouseEvent . onMouseleave = onMouseleave ;
336198 }
337199 if ( props . allowChecked ) {
338- mouseEvent . onMousedown = handleMouseDown ;
200+ mouseEvent . onMousedown = onMousedown ;
339201 }
340202
341203 window . addEventListener ( 'scroll' , resetLeftTop ) ;
@@ -348,11 +210,12 @@ export function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props:
348210 commentLeft,
349211 commentTop,
350212 mouseEvent,
351- updateCheckedLineClass,
352213 clearCheckedLines,
353214 onCommentMouseLeave,
354215 onCommentIconClick,
355216 insertComment,
356217 removeComment,
218+ updateLineNumberMap,
219+ updateCheckedLine,
357220 } ;
358221}
0 commit comments