1+ import { toRefs } from 'vue' ;
12import type { Ref } from 'vue' ;
2- import type { OutputFormat } from '../code-review-types' ;
3+ import type { CodeReviewProps , ExpandDirection } from '../code-review-types' ;
34import { ExpandLineReg , FirstLineReg } from '../const' ;
4- import { attachExpandUpDownButton } from '../utils' ;
5+ import {
6+ attachExpandUpDownButton ,
7+ getLineNumberFormDataset ,
8+ parseDiffCode ,
9+ updateExpandLineCount ,
10+ updateLineNumberInDataset ,
11+ insertIncrementLineToPage ,
12+ ifRemoveExpandLine ,
13+ } from '../utils' ;
14+
15+ export function useCodeReviewExpand ( reviewContentRef : Ref < HTMLElement > , props : CodeReviewProps ) {
16+ const { outputFormat, expandAllThreshold, codeLoader } = toRefs ( props ) ;
517
6- export function useCodeReviewExpand ( reviewContentRef : Ref < HTMLElement > , expandAllThreshold : number , outputFormat : OutputFormat ) {
718 const processSideBySide = ( ) => {
819 const [ leftTable , rightTable ] = reviewContentRef . value . querySelectorAll ( 'table' ) ;
920 const trNodes = Array . from ( leftTable . querySelectorAll ( 'tr' ) ) ;
@@ -24,7 +35,8 @@ export function useCodeReviewExpand(reviewContentRef: Ref<HTMLElement>, expandAl
2435 } else if ( lineIndex > 0 && lineIndex < totalLines - 1 && nextLineIndex in trNodes && prevLineIndex in trNodes ) {
2536 const preLineChildren = Array . from ( trNodes [ prevLineIndex ] . children ) as HTMLElement [ ] ;
2637 const nextLineChildren = Array . from ( trNodes [ nextLineIndex ] . children ) as HTMLElement [ ] ;
27- const isExpandAll = parseInt ( nextLineChildren [ 0 ] . innerText ) - parseInt ( preLineChildren [ 0 ] . innerText ) - 1 < expandAllThreshold ;
38+ const isExpandAll =
39+ parseInt ( nextLineChildren [ 0 ] . innerText ) - parseInt ( preLineChildren [ 0 ] . innerText ) - 1 < expandAllThreshold . value ;
2840 attachExpandUpDownButton ( lineNumberBox , isExpandAll ? 'all' : 'updown' ) ;
2941 }
3042 }
@@ -59,34 +71,99 @@ export function useCodeReviewExpand(reviewContentRef: Ref<HTMLElement>, expandAl
5971 const nextLineIndex = lineIndex + 1 ;
6072 const prevLineIndex = lineIndex - 1 ;
6173 if ( lineIndex === 0 && nextLineIndex in trNodes ) {
74+ updateLineNumberInDataset ( trNodes [ lineIndex ] , expandAllThreshold . value , 'top' ) ;
6275 attachExpandUpDownButton ( lineNumberBox , 'up' ) ;
6376 } else if ( lineIndex > 0 && lineIndex < totalLines - 1 && nextLineIndex in trNodes && prevLineIndex in trNodes ) {
6477 const prevTdNodes = Array . from ( trNodes [ prevLineIndex ] . children ) as HTMLElement [ ] ;
6578 const prevLineNumber = parseInt ( ( prevTdNodes [ 0 ] . children [ 0 ] as HTMLElement ) . innerText ) ;
6679 const nextTdNodes = Array . from ( trNodes [ nextLineIndex ] . children ) as HTMLElement [ ] ;
6780 const nextLineNumber = parseInt ( ( nextTdNodes [ 0 ] . children [ 0 ] as HTMLElement ) . innerText ) ;
68- const isExpandAll = nextLineNumber - prevLineNumber - 1 < expandAllThreshold ;
81+ updateLineNumberInDataset ( trNodes [ lineIndex ] , expandAllThreshold . value , 'middle' ) ;
82+ const isExpandAll = nextLineNumber - prevLineNumber <= expandAllThreshold . value ;
6983 attachExpandUpDownButton ( lineNumberBox , isExpandAll ? 'all' : 'updown' ) ;
7084 }
7185 }
7286 }
7387
74- const loadMoreLine = trNodes [ 0 ] . cloneNode ( true ) as HTMLElement ;
88+ const loadMoreLine = trNodes [ 0 ] . cloneNode ( true ) as HTMLTableRowElement ;
7589 loadMoreLine . children [ 0 ] . removeChild ( loadMoreLine . children [ 0 ] . children [ 0 ] ) ;
7690 ( loadMoreLine . children [ 1 ] as HTMLElement ) . innerText = '' ;
77- ( loadMoreLine . children [ 1 ] as HTMLElement ) . style . height = '20px' ;
78- const lastTrNode = trNodes [ totalLines - 1 ] . children ;
79- const leftLineStart = parseInt ( ( lastTrNode [ 0 ] . children [ 0 ] as HTMLElement ) . innerText ) + 1 ;
80- const rightLineStart = parseInt ( ( lastTrNode [ 0 ] . children [ 1 ] as HTMLElement ) . innerText ) + 1 ;
81- if ( leftLineStart && rightLineStart ) {
82- attachExpandUpDownButton ( loadMoreLine . children [ 0 ] as HTMLElement , 'down' ) ;
83- }
8491 trNodes [ 0 ] . parentElement ?. appendChild ( loadMoreLine ) ;
92+ updateLineNumberInDataset ( loadMoreLine , expandAllThreshold . value , 'bottom' ) ;
93+ attachExpandUpDownButton ( loadMoreLine . children [ 0 ] as HTMLElement , 'down' ) ;
94+ } ;
95+
96+ const insertIncrementCode = ( code : string , direction : 'up' | 'down' , referenceDom : HTMLElement | null | undefined ) => {
97+ if ( ! referenceDom ) {
98+ return ;
99+ }
100+ // 无更新内容,删除展开按钮所在行
101+ if ( ! code ) {
102+ return referenceDom ?. remove ( ) ;
103+ }
104+ const prefix = '--- updated_at\tJan 1, 2019, 0:0:0 AM\n+++ updated_at\tJan 1, 2019, 0:0:0 AM\n' ;
105+ const container = document . createElement ( 'div' ) ;
106+ // 解析code
107+ parseDiffCode ( container , prefix + code , outputFormat . value ) ;
108+
109+ const trNodes = Array . from ( container . querySelectorAll ( 'tr' ) ) ;
110+ const expandLine = trNodes . find ( ( element ) => ( element . children [ 1 ] as HTMLElement ) ?. innerText . trim ( ) . match ( ExpandLineReg ) ) ;
111+ // 不包含 @@ -x,x +y,y @@,视为无效code
112+ if ( ! expandLine ) {
113+ return ;
114+ }
115+
116+ // 将有效代码行插入页面
117+ insertIncrementLineToPage ( referenceDom , trNodes , direction ) ;
118+
119+ // 判断是否需要移除展开行,代码若已全部展开,不再需要展开行
120+ const removedExpandLine = ifRemoveExpandLine ( referenceDom , expandLine , direction ) ;
121+ // 已经移除展开行,则不需要更新展开行的内容和边界数据
122+ if ( removedExpandLine ) {
123+ return ;
124+ }
125+
126+ // 更新展开行内容,@@ -x,x +y,y @@
127+ updateExpandLineCount ( referenceDom , expandLine ) ;
128+
129+ // 更新展开行节点保存的边界数据
130+ if ( direction === 'up' ) {
131+ if ( ! referenceDom . previousElementSibling ) {
132+ // 向上展开在第一行
133+ updateLineNumberInDataset ( referenceDom , expandAllThreshold . value , 'top' ) ;
134+ } else {
135+ // 向上展开在中间行
136+ updateLineNumberInDataset ( referenceDom , expandAllThreshold . value , 'middle' , true ) ;
137+ }
138+ } else {
139+ if ( referenceDom . nextElementSibling ) {
140+ // 向下展开在中间行
141+ updateLineNumberInDataset ( referenceDom , expandAllThreshold . value , 'middle' , true ) ;
142+ } else {
143+ // 向下展开在末尾
144+ updateLineNumberInDataset ( referenceDom , expandAllThreshold . value , 'bottom' ) ;
145+ }
146+ }
147+ } ;
148+
149+ const onExpandButtonClick = ( e : Event ) => {
150+ const composedPath = e . composedPath ( ) as HTMLElement [ ] ;
151+ const expandIconDom = composedPath . find ( ( element ) => element . classList ?. contains ( 'expand-icon' ) ) ;
152+ if ( expandIconDom ) {
153+ const expandDirection = Array . from ( expandIconDom . classList )
154+ . find ( ( item ) => item . endsWith ( 'expand' ) )
155+ ?. split ( '-' ) [ 0 ] ;
156+ const direction : ExpandDirection = expandDirection === 'up' || expandDirection === 'all' ? 'up' : 'down' ;
157+ const [ leftLineStart , leftLineEnd , rightLineStart , rightLineEnd ] = getLineNumberFormDataset ( expandIconDom , expandAllThreshold . value ) ;
158+ codeLoader ?. value ?.( [ leftLineStart , leftLineEnd , rightLineStart , rightLineEnd ] , ( code : string ) => {
159+ insertIncrementCode ( code , direction , expandIconDom . parentElement ?. parentElement ) ;
160+ } ) ;
161+ }
85162 } ;
86163
87164 const insertExpandButton = ( ) => {
88- outputFormat === 'side-by-side' ? processSideBySide ( ) : processLineByLine ( ) ;
165+ outputFormat . value === 'side-by-side' ? processSideBySide ( ) : processLineByLine ( ) ;
89166 } ;
90167
91- return { insertExpandButton } ;
168+ return { insertExpandButton, onExpandButtonClick } ;
92169}
0 commit comments