@@ -69,7 +69,7 @@ angular.module('ui.scroll', [])
69
69
wrapper .scope .$destroy ()
70
70
]
71
71
72
- Buffer = (itemName , $scope , linker , datasource , bufferSize )->
72
+ Buffer = (itemName , $scope , linker , bufferSize )->
73
73
74
74
buffer = Object .create Array .prototype
75
75
@@ -78,6 +78,16 @@ angular.module('ui.scroll', [])
78
78
79
79
buffer .size = bufferSize
80
80
81
+ buffer .append = (items ) ->
82
+ for item in items
83
+ ++ buffer .next
84
+ buffer .insert ' append' , item
85
+
86
+ buffer .prepend = (items ) ->
87
+ for item in items .reverse ()
88
+ -- buffer .first
89
+ buffer .insert ' prepend' , item
90
+
81
91
# inserts wrapped element in the buffer
82
92
# the first argument is either operation keyword (see below) or a number for operation 'insert'
83
93
# for insert the number is the index for the buffer element the new one have to be inserted after
@@ -113,35 +123,43 @@ angular.module('ui.scroll', [])
113
123
buffer .splice buffer .indexOf (arg1), 1
114
124
removeElementAnimated arg1
115
125
126
+
127
+ minIndex = Number .MAX_VALUE
128
+ maxIndex = Number .MIN_VALUE
129
+
116
130
reset = ->
117
131
buffer .eof = false
118
132
buffer .bof = false
119
133
buffer .first = origin
120
134
buffer .next = origin
121
135
buffer .localMinIndex = origin
122
136
137
+ minIndex = Number .MAX_VALUE
138
+ maxIndex = Number .MIN_VALUE
139
+
140
+ buffer .setUpper = ->
141
+ if buffer .eof
142
+ maxIndex = buffer .next - 1
143
+ else
144
+ maxIndex = Math .max buffer .next - 1 , maxIndex
145
+
146
+ buffer .maxIndex = -> maxIndex
147
+
148
+ buffer .setLower = ->
149
+ if buffer .bof
150
+ minIndex = buffer .first
151
+ else
152
+ minIndex = Math .min buffer .first , minIndex
153
+
154
+ buffer .minIndex = -> minIndex
155
+
123
156
# clears the buffer
124
157
buffer .clear = ->
125
158
buffer .remove (0 , buffer .length )
126
159
reset ()
127
160
128
161
reset ()
129
162
130
- buffer .minIndex = (value ) ->
131
- if arguments .length
132
- if buffer .bof
133
- datasource .minIndex = value
134
- else
135
- datasource .minIndex = Math .min value, datasource .minIndex || Number .MAX_VALUE
136
- buffer .localMinIndex = datasource .minIndex
137
- else
138
- offset = buffer .localMinIndex - (datasource .minIndex || origin)
139
- buffer .localMinIndex -= offset
140
- offset : offset # if minIndex is decremented outside of the scroller offset value is by how much
141
- value : buffer .localMinIndex
142
-
143
- buffer .maxIndex = -> datasource .maxIndex || origin
144
-
145
163
buffer
146
164
147
165
Padding = (template ) ->
@@ -160,15 +178,15 @@ angular.module('ui.scroll', [])
160
178
result
161
179
162
180
163
- Viewport = (buffer , element , controllers , padding ) ->
181
+ Viewport = (buffer , element , controllers , attrs ) ->
164
182
165
183
viewport = if controllers[0 ] and controllers[0 ].viewport then controllers[0 ].viewport else angular .element (window )
166
184
viewport .css ({' overflow-y' : ' auto' , ' display' : ' block' })
167
185
168
186
topPadding = null
169
187
bottomPadding = null
170
188
171
- bufferPadding = -> viewport .outerHeight () * Math .max (0.1 , + padding .padding || 0.1 ) # some extra space to initiate preload
189
+ bufferPadding = -> viewport .outerHeight () * Math .max (0.1 , + attrs .padding || 0.1 ) # some extra space to initiate preload
172
190
173
191
viewport .createPaddingElements = (template ) ->
174
192
topPadding = new Padding template
@@ -195,7 +213,7 @@ angular.module('ui.scroll', [])
195
213
viewport .clipBottom = ->
196
214
# clip the invisible items off the bottom
197
215
overage = 0
198
- overageBottom = viewport .outerHeight () + viewport .averageItemHeight * (buffer .size )
216
+ overageBottom = viewport .bottomVisiblePos () + viewport .averageItemHeight * (buffer .size )
199
217
for i in [buffer .length - 1 .. 0 ]
200
218
item = buffer[i]
201
219
if item .element .offset ().top > overageBottom
@@ -213,7 +231,7 @@ angular.module('ui.scroll', [])
213
231
# clip the invisible items off the top
214
232
overage = 0
215
233
heightIncrement = 0
216
- overageTop = ( - 1 ) * viewport .averageItemHeight * buffer .size
234
+ overageTop = viewport . topVisiblePos () - viewport .averageItemHeight * buffer .size
217
235
for item in buffer
218
236
if item .element .offset ().top < overageTop
219
237
heightIncrement += item .element .outerHeight ()
@@ -224,17 +242,34 @@ angular.module('ui.scroll', [])
224
242
buffer .remove (0 , overage)
225
243
buffer .first += overage
226
244
227
- viewport .adjustPadding = () ->
245
+ ###
246
+ buffer.minIndex = (value) ->
247
+ if arguments.length
248
+ if buffer.bof
249
+ datasource.minIndex = value
250
+ else
251
+ datasource.minIndex = Math.min value, datasource.minIndex || Number.MAX_VALUE
252
+ buffer.localMinIndex = datasource.minIndex
253
+ else
254
+ offset = buffer.localMinIndex - (datasource.minIndex || origin)
255
+ buffer.localMinIndex -= offset
256
+ offset: offset #if minIndex is decremented outside of the scroller offset value is by how much
257
+ value: buffer.localMinIndex
258
+ ###
259
+
260
+
261
+ viewport .adjustPadding = ->
228
262
return if not buffer .length
229
263
viewport .averageItemHeight = (buffer[buffer .length - 1 ].element .offset ().top +
230
264
buffer[buffer .length - 1 ].element .outerHeight (true ) -
231
265
buffer[0 ].element .offset ().top ) / buffer .length
266
+ topPadding .height (buffer .first - buffer .minIndex ()) * viewport .averageItemHeight
267
+ bottomPadding .height (buffer .maxIndex () - buffer .next + 1 ) * viewport .averageItemHeight
268
+
269
+ viewport .syncDatasource = ->
232
270
minIndex = buffer .minIndex ()
233
- topPadding .height (buffer .first - minIndex .value ) * viewport .averageItemHeight
234
271
if minIndex .offset
235
272
viewport .scrollTop (minIndex .offset * viewport .averageItemHeight )
236
- # console.log "id #{padding.id} min #{minIndex.value} top #{viewport.scrollTop()} offs #{minIndex.offset * viewport.averageItemHeight}"
237
- bottomPadding .height (buffer .maxIndex () - buffer .next + 1 ) * viewport .averageItemHeight
238
273
239
274
viewport .adjustScrollTop = (height ) ->
240
275
paddingHeight = topPadding .height () - height
@@ -282,15 +317,11 @@ angular.module('ui.scroll', [])
282
317
adjustBuffer ()
283
318
284
319
this .append = (newItems ) ->
285
- for item in newItems
286
- ++ buffer .next
287
- buffer .insert ' append' , item
320
+ buffer .append newItems
288
321
adjustBuffer ()
289
322
290
323
this .prepend = (newItems ) ->
291
- for item in newItems .reverse ()
292
- -- buffer .first
293
- buffer .insert ' prepend' , item
324
+ buffer .prepend newItems
294
325
adjustBuffer ()
295
326
296
327
setTopVisible = if $attr .topVisible then $parse ($attr .topVisible ).assign else ->
@@ -354,7 +385,7 @@ angular.module('ui.scroll', [])
354
385
355
386
pending = []
356
387
357
- buffer = new Buffer (itemName, $scope, linker, datasource, bufferSize)
388
+ buffer = new Buffer (itemName, $scope, linker, bufferSize)
358
389
359
390
viewport = new Viewport (buffer, element, controllers, $attr)
360
391
@@ -456,6 +487,8 @@ angular.module('ui.scroll', [])
456
487
adjustBuffer rid
457
488
else
458
489
viewport .adjustPadding ()
490
+ if not pending .length
491
+ viewport .syncDatasource datasource
459
492
460
493
keepFetching
461
494
@@ -490,12 +523,10 @@ angular.module('ui.scroll', [])
490
523
fetch (rid)
491
524
492
525
fetch = (rid ) ->
493
- # log "Running fetch... #{{true:'bottom', false: 'top'}[direction]} pending #{pending.length}"
494
526
if pending[0 ] # scrolling down
495
527
if buffer .length && ! viewport .shouldLoadBottom ()
496
528
adjustBufferAfterFetch rid
497
529
else
498
- # log "appending... requested #{bufferSize} records starting from #{next}"
499
530
datasource .get buffer .next , bufferSize,
500
531
(result ) ->
501
532
return if (rid and rid isnt ridActual) or $scope .$$destroyed
@@ -504,20 +535,13 @@ angular.module('ui.scroll', [])
504
535
# log 'eof is reached'
505
536
if result .length > 0
506
537
viewport .clipTop ()
507
- for item in result
508
- ++ buffer .next
509
- buffer .insert ' append' , item
510
- # log 'appended: requested ' + bufferSize + ' received ' + result.length + ' buffer size ' + buffer.length + ' first ' + first + ' next ' + next
511
- if buffer .eof
512
- datasource .maxIndex = buffer .next - 1
513
- else
514
- datasource .maxIndex = Math .max buffer .next - 1 , datasource .maxIndex || Number .MIN_VALUE
538
+ buffer .append result
539
+ buffer .setUpper ()
515
540
adjustBufferAfterFetch rid
516
541
else
517
542
if buffer .length && ! viewport .shouldLoadTop ()
518
543
adjustBufferAfterFetch rid
519
544
else
520
- # log "prepending... requested #{size} records starting from #{start}"
521
545
datasource .get buffer .first - bufferSize, bufferSize,
522
546
(result ) ->
523
547
return if (rid and rid isnt ridActual) or $scope .$$destroyed
@@ -526,11 +550,8 @@ angular.module('ui.scroll', [])
526
550
# log 'bof is reached'
527
551
if result .length > 0
528
552
viewport .clipBottom () if buffer .length
529
- for i in [result .length - 1 .. 0 ]
530
- -- buffer .first
531
- buffer .insert ' prepend' , result[i]
532
- # log 'prepended: requested ' + bufferSize + ' received ' + result.length + ' buffer size ' + buffer.length + ' first ' + first + ' next ' + next
533
- buffer .minIndex buffer .first
553
+ buffer .prepend result
554
+ buffer .setLower ()
534
555
adjustBufferAfterFetch rid
535
556
536
557
# events and bindings
0 commit comments