@@ -110,6 +110,18 @@ angular.module('ui.scroll', [])
110
110
# clears the buffer
111
111
buffer .clear = ->
112
112
buffer .remove (0 , buffer .length )
113
+ buffer .eof = false
114
+ buffer .bof = false
115
+ buffer .first = 1
116
+ buffer .next = 1
117
+
118
+ buffer .eof = false
119
+
120
+ buffer .bof = false
121
+
122
+ buffer .first = 1
123
+
124
+ buffer .next = 1
113
125
114
126
buffer
115
127
@@ -129,7 +141,7 @@ angular.module('ui.scroll', [])
129
141
result
130
142
131
143
132
- Viewport = (buffer , element , controllers ) ->
144
+ Viewport = (buffer , element , controllers , padding ) ->
133
145
134
146
viewport = if controllers[0 ] and controllers[0 ].viewport then controllers[0 ].viewport else angular .element (window )
135
147
viewport .css ({' overflow-y' : ' auto' , ' display' : ' block' })
@@ -138,6 +150,8 @@ angular.module('ui.scroll', [])
138
150
139
151
bottomPadding = null
140
152
153
+ bufferPadding = -> viewport .outerHeight () * Math .max (0.1 , + padding || 0.1 ) # some extra space to initiate preload
154
+
141
155
viewport .createPaddingElements = (template ) ->
142
156
143
157
topPadding = new Padding template
@@ -188,7 +202,7 @@ angular.module('ui.scroll', [])
188
202
if overage > 0
189
203
viewport .bottomPadding (viewport .bottomPadding () + bottomHeight)
190
204
buffer .remove (buffer .length - overage, buffer .length )
191
- next -= overage
205
+ buffer . next -= overage
192
206
193
207
viewport .shouldLoadTop = ->
194
208
! buffer .bof && (viewport .topDataPos () > viewport .topVisiblePos () - bufferPadding ())
@@ -212,7 +226,7 @@ angular.module('ui.scroll', [])
212
226
if overage > 0
213
227
viewport .topPadding (viewport .topPadding () + topHeight)
214
228
buffer .remove (0 , overage)
215
- first += overage
229
+ buffer . first += overage
216
230
217
231
218
232
@@ -251,14 +265,10 @@ angular.module('ui.scroll', [])
251
265
# initial settings
252
266
253
267
ridActual = 0 # current data revision id
254
- first = 1
255
- next = 1
256
- buffer = new Buffer (itemName, $scope, linker)
257
268
pending = []
258
- eof = false
259
- bof = false
269
+ buffer = new Buffer (itemName, $scope, linker)
260
270
261
- viewport = new Viewport (buffer, element, controllers)
271
+ viewport = new Viewport (buffer, element, controllers, $attr . padding )
262
272
263
273
# Padding element builder
264
274
#
@@ -296,67 +306,11 @@ angular.module('ui.scroll', [])
296
306
297
307
reloadImpl = ->
298
308
dismissPendingRequests ()
299
- first = 1
300
- next = 1
301
309
buffer .clear ()
302
310
viewport .topPadding (0 )
303
311
viewport .bottomPadding (0 )
304
- eof = false
305
- bof = false
306
312
adjustBuffer ridActual
307
313
308
- shouldLoadBottom = ->
309
- ! eof && viewport .bottomDataPos () < viewport .bottomVisiblePos () + bufferPadding ()
310
-
311
- clipBottom = ->
312
- # clip the invisible items off the bottom
313
- bottomHeight = 0
314
- overage = 0
315
-
316
- for i in [buffer .length - 1 .. 0 ]
317
- item = buffer[i]
318
- itemTop = item .element .offset ().top
319
- newRow = rowTop isnt itemTop
320
- rowTop = itemTop
321
- itemHeight = item .element .outerHeight (true ) if newRow
322
- if (viewport .bottomDataPos () - bottomHeight - itemHeight > viewport .bottomVisiblePos () + bufferPadding ())
323
- bottomHeight += itemHeight if newRow
324
- overage++
325
- eof = false
326
- else
327
- break if newRow
328
- overage++
329
-
330
- if overage > 0
331
- viewport .bottomPadding (viewport .bottomPadding () + bottomHeight)
332
- buffer .remove (buffer .length - overage, buffer .length )
333
- next -= overage
334
- # log 'clipped off bottom ' + overage + ' bottom padding ' + viewport.bottomPadding()
335
-
336
- shouldLoadTop = ->
337
- ! bof && (viewport .topDataPos () > viewport .topVisiblePos () - bufferPadding ())
338
-
339
- clipTop = ->
340
- # clip the invisible items off the top
341
- topHeight = 0
342
- overage = 0
343
- for item in buffer
344
- itemTop = item .element .offset ().top
345
- newRow = rowTop isnt itemTop
346
- rowTop = itemTop
347
- itemHeight = item .element .outerHeight (true ) if newRow
348
- if (viewport .topDataPos () + topHeight + itemHeight < viewport .topVisiblePos () - bufferPadding ())
349
- topHeight += itemHeight if newRow
350
- overage++
351
- bof = false
352
- else
353
- break if newRow
354
- overage++
355
- if overage > 0
356
- viewport .topPadding (viewport .topPadding () + topHeight)
357
- buffer .remove (0 , overage)
358
- first += overage
359
-
360
314
enqueueFetch = (rid , direction )->
361
315
if ! adapter .isLoading
362
316
loading (true )
@@ -425,7 +379,7 @@ angular.module('ui.scroll', [])
425
379
viewport .scrollTop (viewport .scrollTop () + heightIncrement)
426
380
427
381
# re-index the buffer
428
- item .scope .$index = first + i for item,i in buffer
382
+ item .scope .$index = buffer . first + i for item,i in buffer
429
383
430
384
# schedule another adjustBuffer after animation completion
431
385
if (promises .length )
@@ -455,10 +409,10 @@ angular.module('ui.scroll', [])
455
409
456
410
processBufferedItems (rid)
457
411
458
- if shouldLoadBottom ()
412
+ if viewport . shouldLoadBottom ()
459
413
enqueueFetch (rid, true )
460
414
else
461
- if shouldLoadTop ()
415
+ if viewport . shouldLoadTop ()
462
416
enqueueFetch (rid, false )
463
417
464
418
if pending .length == 0
@@ -471,11 +425,11 @@ angular.module('ui.scroll', [])
471
425
472
426
keepFetching = processBufferedItems (rid)
473
427
474
- if shouldLoadBottom ()
428
+ if viewport . shouldLoadBottom ()
475
429
# keepFetching = true means that at least one item app/prepended in the last batch had height > 0
476
430
enqueueFetch (rid, true ) if keepFetching
477
431
else
478
- if shouldLoadTop ()
432
+ if viewport . shouldLoadTop ()
479
433
# pending[0] = true means that previous fetch was appending. We need to force at least one prepend
480
434
# BTW there will always be at least 1 element in the pending array because bottom is fetched first
481
435
enqueueFetch (rid, false ) if keepFetching || pending[0 ]
@@ -490,40 +444,40 @@ angular.module('ui.scroll', [])
490
444
fetch = (rid ) ->
491
445
# log "Running fetch... #{{true:'bottom', false: 'top'}[direction]} pending #{pending.length}"
492
446
if pending[0 ] # scrolling down
493
- if buffer .length && ! shouldLoadBottom ()
447
+ if buffer .length && ! viewport . shouldLoadBottom ()
494
448
adjustBufferAfterFetch rid
495
449
else
496
450
# log "appending... requested #{bufferSize} records starting from #{next}"
497
- datasource .get next, bufferSize,
451
+ datasource .get buffer . next , bufferSize,
498
452
(result ) ->
499
453
return if (rid and rid isnt ridActual) or $scope .$$destroyed
500
454
if result .length < bufferSize
501
- eof = true
455
+ buffer . eof = true
502
456
viewport .bottomPadding (0 )
503
457
# log 'eof is reached'
504
458
if result .length > 0
505
- clipTop ()
459
+ viewport . clipTop ()
506
460
for item in result
507
- ++ next
461
+ ++ buffer . next
508
462
buffer .insert ' append' , item
509
463
# log 'appended: requested ' + bufferSize + ' received ' + result.length + ' buffer size ' + buffer.length + ' first ' + first + ' next ' + next
510
464
adjustBufferAfterFetch rid
511
465
else
512
- if buffer .length && ! shouldLoadTop ()
466
+ if buffer .length && ! viewport . shouldLoadTop ()
513
467
adjustBufferAfterFetch rid
514
468
else
515
469
# log "prepending... requested #{size} records starting from #{start}"
516
- datasource .get first- bufferSize, bufferSize,
470
+ datasource .get buffer . first - bufferSize, bufferSize,
517
471
(result ) ->
518
472
return if (rid and rid isnt ridActual) or $scope .$$destroyed
519
473
if result .length < bufferSize
520
- bof = true
474
+ buffer . bof = true
521
475
viewport .topPadding (0 )
522
476
# log 'bof is reached'
523
477
if result .length > 0
524
- clipBottom () if buffer .length
478
+ viewport . clipBottom () if buffer .length
525
479
for i in [result .length - 1 .. 0 ]
526
- -- first
480
+ -- buffer . first
527
481
buffer .insert ' prepend' , result[i]
528
482
# log 'prepended: requested ' + bufferSize + ' received ' + result.length + ' buffer size ' + buffer.length + ' first ' + first + ' next ' + next
529
483
adjustBufferAfterFetch rid
@@ -539,7 +493,7 @@ angular.module('ui.scroll', [])
539
493
wheelHandler = (event ) ->
540
494
scrollTop = viewport[0 ].scrollTop
541
495
yMax = viewport[0 ].scrollHeight - viewport[0 ].clientHeight
542
- if (scrollTop is 0 and not bof) or (scrollTop is yMax and not eof)
496
+ if (scrollTop is 0 and not buffer . bof ) or (scrollTop is yMax and not buffer . eof )
543
497
event .preventDefault ()
544
498
545
499
viewport .bind ' resize' , resizeAndScrollHandler
@@ -585,23 +539,23 @@ angular.module('ui.scroll', [])
585
539
else
586
540
# arg1 is item index, arg2 is the newItems array
587
541
if arg1% 1 == 0 # checking if it is an integer
588
- if 0 <= arg1- first < buffer .length
589
- applyUpdate buffer[arg1 - first], arg2
542
+ if 0 <= arg1- buffer . first < buffer .length
543
+ applyUpdate buffer[arg1 - buffer . first ], arg2
590
544
else
591
545
throw new Error ' applyUpdates - ' + arg1 + ' is not a valid index'
592
546
adjustBuffer ridActual
593
547
594
548
adapter .append = (newItems ) ->
595
549
dismissPendingRequests ()
596
550
for item in newItems
597
- ++ next
551
+ ++ buffer . next
598
552
buffer .insert ' append' , item
599
553
adjustBuffer ridActual
600
554
601
555
adapter .prepend = (newItems ) ->
602
556
dismissPendingRequests ()
603
557
for item in newItems .reverse ()
604
- -- first
558
+ -- buffer . first
605
559
buffer .insert ' prepend' , item
606
560
adjustBuffer ridActual
607
561
0 commit comments