@@ -57,3 +57,77 @@ fileHeaders.forEach(header => {
5757const scrollIfNeeded = elem => {
5858 elem . getBoundingClientRect ( ) . top < 0 && elem . scrollIntoView ( true )
5959}
60+
61+ const MAX_EXPAND_CONTEXT_LINES = 20
62+
63+ document . addEventListener ( 'DOMContentLoaded' , e => {
64+ document . querySelectorAll ( '.ghd-expand-up' ) . forEach ( expandUp => {
65+ expandUp . addEventListener ( 'click' , e => {
66+ const { fileName, packageName, version, lineAfter, lineBefore, patch} = gatherInfo ( expandUp )
67+
68+ // expandUp always follows by diff line.. so we take the number
69+ const toLine = numberFrom ( lineAfter ) - 1
70+
71+ const _fromLine = lineBefore ? numberFrom ( lineBefore ) + 1 : 1
72+ const fromLine = Math . max ( toLine - MAX_EXPAND_CONTEXT_LINES , _fromLine )
73+
74+ const _rightLine = lineBefore ? numberTo ( lineBefore ) + 1 : 1
75+ const rightLine = Math . max ( toLine - MAX_EXPAND_CONTEXT_LINES , _rightLine )
76+
77+ fetchChunkAndInsert ( { target : lineAfter , packageName, version, fromLine, toLine, rightLine, fileName, patch} )
78+ } )
79+ } )
80+
81+ document . querySelectorAll ( '.ghd-expand-down' ) . forEach ( expandDown => {
82+ expandDown . addEventListener ( 'click' , e => {
83+ const { fileName, packageName, version, lineAfter, lineBefore, patch} = gatherInfo ( expandDown )
84+
85+ const fromLine = numberFrom ( lineBefore ) + 1
86+ const rightLine = numberTo ( lineBefore ) + 1
87+
88+ const _toLine = lineAfter ? numberFrom ( lineAfter ) - 1 : Infinity
89+ const toLine = Math . min ( fromLine + MAX_EXPAND_CONTEXT_LINES , _toLine )
90+
91+ fetchChunkAndInsert ( { target : expandDown . closest ( 'tr' ) , packageName, version, fromLine, toLine, rightLine, fileName, patch} )
92+
93+ } )
94+ } )
95+ } )
96+
97+ const numberFrom = line => parseInt ( line . querySelector ( '.ghd-line-number .ghd-line-number-from' ) . textContent . trim ( ) )
98+ const numberTo = line => parseInt ( line . querySelector ( '.ghd-line-number .ghd-line-number-to' ) . textContent . trim ( ) )
99+
100+ const gatherInfo = line => {
101+ const patch = line . closest ( '.ghd-file' )
102+ const { fileName, packageName, version} = patch . querySelector ( '.ghd-file-header' ) . dataset
103+
104+ const lineAfter = line . closest ( 'tr' ) . nextElementSibling
105+ const lineBefore = line . closest ( 'tr' ) . previousElementSibling
106+
107+ return { fileName, packageName, version, lineAfter, lineBefore, patch}
108+ }
109+
110+ const fetchChunkAndInsert = params => {
111+ if ( ! ( params . fromLine && params . toLine ) ||
112+ ( params . fromLine >= params . toLine ) ) {
113+ return
114+ }
115+
116+ const path = `/diff/${ params . packageName } /${ params . version } /expand/${ params . fromLine } /${ params . toLine } /${ params . rightLine } `
117+ const url = new URL ( path , window . location )
118+ url . searchParams . append ( 'file_name' , params . fileName )
119+
120+ fetch ( url )
121+ . then ( response => response . json ( ) )
122+ . then ( ( { chunk, lines, errors} ) => {
123+ if ( errors ) { return }
124+ const context = document . createElement ( 'template' )
125+ context . innerHTML = chunk . trim ( )
126+ const patchBody = params . patch . querySelector ( 'tbody' )
127+
128+ Array . prototype . reduceRight . call ( context . content . childNodes , ( target , line ) => {
129+ return patchBody . insertBefore ( line , target )
130+ } , params . target )
131+ } )
132+ . catch ( console . error )
133+ }
0 commit comments