@@ -57,3 +57,77 @@ fileHeaders.forEach(header => {
57
57
const scrollIfNeeded = elem => {
58
58
elem . getBoundingClientRect ( ) . top < 0 && elem . scrollIntoView ( true )
59
59
}
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