@@ -234,120 +234,133 @@ angular.module('ui.scroll', [])
234234 return viewport . outerHeight ( ) * Math . max ( 0.1 , + attrs . padding || 0.1 ) ; // some extra space to initiate preload
235235 }
236236
237- viewport . createPaddingElements = function ( template ) {
238- topPadding = new Padding ( template ) ;
239- bottomPadding = new Padding ( template ) ;
240- element . before ( topPadding ) ;
241- return element . after ( bottomPadding ) ;
242- } ;
237+ angular . extend ( viewport , {
238+ createPaddingElements ( template ) {
239+ topPadding = new Padding ( template ) ;
240+ bottomPadding = new Padding ( template ) ;
241+ element . before ( topPadding ) ;
242+ element . after ( bottomPadding ) ;
243+ } ,
243244
244- viewport . bottomDataPos = function ( ) {
245- var ref ;
246- return ( ( ref = viewport [ 0 ] . scrollHeight ) != null ? ref : viewport [ 0 ] . document . documentElement . scrollHeight ) - bottomPadding . height ( ) ;
247- } ;
245+ bottomDataPos ( ) {
246+ let scrollHeight = viewport [ 0 ] . scrollHeight ;
247+ scrollHeight = scrollHeight !== null ? scrollHeight : viewport [ 0 ] . document . documentElement . scrollHeight ;
248248
249- viewport . topDataPos = function ( ) {
250- return topPadding . height ( ) ;
251- } ;
249+ return scrollHeight - bottomPadding . height ( ) ;
250+ } ,
252251
253- viewport . bottomVisiblePos = function ( ) {
254- return viewport . scrollTop ( ) + viewport . outerHeight ( ) ;
255- } ;
252+ topDataPos ( ) {
253+ return topPadding . height ( ) ;
254+ } ,
256255
257- viewport . topVisiblePos = function ( ) {
258- return viewport . scrollTop ( ) ;
259- } ;
256+ bottomVisiblePos ( ) {
257+ return viewport . scrollTop ( ) + viewport . outerHeight ( ) ;
258+ } ,
260259
261- viewport . insertElement = function ( e , sibling ) {
262- return insertElement ( e , sibling || topPadding ) ;
263- } ;
260+ topVisiblePos ( ) {
261+ return viewport . scrollTop ( ) ;
262+ } ,
264263
265- viewport . insertElementAnimated = function ( e , sibling ) {
266- return insertElementAnimated ( e , sibling || topPadding ) ;
267- } ;
264+ insertElement ( e , sibling ) {
265+ return insertElement ( e , sibling || topPadding ) ;
266+ } ,
268267
269- viewport . shouldLoadBottom = function ( ) {
270- return ! buffer . eof && viewport . bottomDataPos ( ) < viewport . bottomVisiblePos ( ) + bufferPadding ( ) ;
271- } ;
268+ insertElementAnimated ( e , sibling ) {
269+ return insertElementAnimated ( e , sibling || topPadding ) ;
270+ } ,
271+
272+ shouldLoadBottom ( ) {
273+ return ! buffer . eof && viewport . bottomDataPos ( ) < viewport . bottomVisiblePos ( ) + bufferPadding ( ) ;
274+ } ,
275+
276+ clipBottom ( ) {
277+ // clip the invisible items off the bottom
278+ let overage = 0 ;
279+ let i = buffer . length - 1 ;
272280
273- viewport . clipBottom = function ( ) {
274- // clip the invisible items off the bottom
275- var i , item , j , overage , ref ;
276- overage = 0 ;
277- for ( i = j = ref = buffer . length - 1 ; ref <= 0 ? j <= 0 : j >= 0 ; i = ref <= 0 ? ++ j : -- j ) {
278- item = buffer [ i ] ;
279- if ( item . element . offset ( ) . top - viewportOffset ( ) . top > viewport . outerHeight ( ) + bufferPadding ( ) ) {
281+ while ( i >= 0 ) {
282+ if ( buffer [ i ] . element . offset ( ) . top - viewportOffset ( ) . top <= viewport . outerHeight ( ) + bufferPadding ( ) ) {
283+ break ;
284+ }
280285 overage ++ ;
281- } else {
282- break ;
286+ i -- ;
283287 }
284- }
285- if ( overage > 0 ) {
286- buffer . eof = false ;
287- buffer . remove ( buffer . length - overage , buffer . length ) ;
288- buffer . next -= overage ;
289- return viewport . adjustPadding ( ) ;
290- }
291- } ;
292288
293- viewport . shouldLoadTop = function ( ) {
294- return ! buffer . bof && ( viewport . topDataPos ( ) > viewport . topVisiblePos ( ) - bufferPadding ( ) ) ;
295- } ;
289+ if ( overage > 0 ) {
290+ buffer . eof = false ;
291+ buffer . remove ( buffer . length - overage , buffer . length ) ;
292+ buffer . next -= overage ;
293+ viewport . adjustPadding ( ) ;
294+ }
295+ } ,
296296
297- viewport . clipTop = function ( ) {
298- // clip the invisible items off the top
299- var item , j , len , overage , overageHeight ;
300- overage = 0 ;
301- overageHeight = 0 ;
302- for ( j = 0 , len = buffer . length ; j < len ; j ++ ) {
303- item = buffer [ j ] ;
304- if ( item . element . offset ( ) . top - viewportOffset ( ) . top + item . element . outerHeight ( true ) < ( - 1 ) * bufferPadding ( ) ) {
297+ shouldLoadTop ( ) {
298+ return ! buffer . bof && ( viewport . topDataPos ( ) > viewport . topVisiblePos ( ) - bufferPadding ( ) ) ;
299+ } ,
300+
301+ clipTop ( ) {
302+ // clip the invisible items off the top
303+ let overage = 0 ;
304+ let overageHeight = 0 ;
305+
306+ buffer . some ( ( item ) => {
307+ if ( item . element . offset ( ) . top - viewportOffset ( ) . top + item . element . outerHeight ( true ) >= ( - 1 ) * bufferPadding ( ) ) {
308+ // break the loop
309+ return true ;
310+ }
305311 overageHeight += item . element . outerHeight ( true ) ;
306312 overage ++ ;
307- } else {
308- break ;
313+ } ) ;
314+
315+ if ( overage > 0 ) {
316+ // we need to adjust top padding element before items are removed from top
317+ // to avoid strange behaviour of scroll bar during remove top items when we are at the very bottom
318+ topPadding . height ( topPadding . height ( ) + overageHeight ) ;
319+ buffer . bof = false ;
320+ buffer . remove ( 0 , overage ) ;
321+ buffer . first += overage ;
309322 }
310- }
311- if ( overage > 0 ) {
312- // we need to adjust top padding element before items are removed from top
313- // to avoid strange behaviour of scroll bar during remove top items when we are at the very bottom
314- topPadding . height ( topPadding . height ( ) + overageHeight ) ;
315- buffer . bof = false ;
316- buffer . remove ( 0 , overage ) ;
317- return buffer . first += overage ;
318- }
319- } ;
323+ } ,
320324
321- viewport . adjustPadding = function ( ) {
322- if ( ! buffer . length ) {
323- return ;
324- }
325- averageItemHeight = ( buffer [ buffer . length - 1 ] . element . offset ( ) . top + buffer [ buffer . length - 1 ] . element . outerHeight ( true ) - buffer [ 0 ] . element . offset ( ) . top ) / buffer . length ;
326- topPadding . height ( ( buffer . first - buffer . minIndex ) * averageItemHeight ) ;
327- return bottomPadding . height ( ( buffer . maxIndex - buffer . next + 1 ) * averageItemHeight ) ;
328- } ;
325+ adjustPadding ( ) {
326+ if ( ! buffer . length ) {
327+ return ;
328+ }
329329
330- viewport . syncDatasource = function ( datasource ) {
331- var delta ;
332- if ( ! buffer . length ) {
333- return ;
334- }
335- delta = buffer . syncDatasource ( datasource ) * averageItemHeight ;
336- topPadding . height ( topPadding . height ( ) + delta ) ;
337- viewport . scrollTop ( viewport . scrollTop ( ) + delta ) ;
338- return viewport . adjustPadding ( ) ;
339- } ;
330+ const bufferFirstEl = buffer [ 0 ] . element ;
331+ const bufferLastEl = buffer [ buffer . length - 1 ] . element ;
340332
341- viewport . adjustScrollTop = function ( height ) {
342- var paddingHeight ;
343- paddingHeight = topPadding . height ( ) - height ;
344- if ( paddingHeight >= 0 ) {
345- return topPadding . height ( paddingHeight ) ;
346- } else {
347- topPadding . height ( 0 ) ;
348- return viewport . scrollTop ( viewport . scrollTop ( ) - paddingHeight ) ;
333+ averageItemHeight = ( bufferLastEl . offset ( ) . top + bufferLastEl . outerHeight ( true ) - bufferFirstEl . offset ( ) . top ) / buffer . length ;
334+ topPadding . height ( ( buffer . first - buffer . minIndex ) * averageItemHeight ) ;
335+
336+ return bottomPadding . height ( ( buffer . maxIndex - buffer . next + 1 ) * averageItemHeight ) ;
337+ } ,
338+
339+ syncDatasource ( datasource ) {
340+ if ( ! buffer . length ) {
341+ return ;
342+ }
343+
344+ const delta = buffer . syncDatasource ( datasource ) * averageItemHeight ;
345+
346+ topPadding . height ( topPadding . height ( ) + delta ) ;
347+
348+ viewport . scrollTop ( viewport . scrollTop ( ) + delta ) ;
349+
350+ viewport . adjustPadding ( ) ;
351+ } ,
352+
353+ adjustScrollTop ( height ) {
354+ const paddingHeight = topPadding . height ( ) - height ;
355+
356+ if ( paddingHeight >= 0 ) {
357+ topPadding . height ( paddingHeight ) ;
358+ } else {
359+ topPadding . height ( 0 ) ;
360+ viewport . scrollTop ( viewport . scrollTop ( ) - paddingHeight ) ;
361+ }
349362 }
350- } ;
363+ } ) ;
351364
352365 return viewport ;
353366 }
0 commit comments