Skip to content

Commit 994dfc0

Browse files
committed
moved min/max index to the buffer object
1 parent b30ad67 commit 994dfc0

File tree

1 file changed

+68
-47
lines changed

1 file changed

+68
-47
lines changed

src/ui-scroll.coffee

Lines changed: 68 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ angular.module('ui.scroll', [])
6969
wrapper.scope.$destroy()
7070
]
7171

72-
Buffer = (itemName, $scope, linker, datasource, bufferSize)->
72+
Buffer = (itemName, $scope, linker, bufferSize)->
7373

7474
buffer = Object.create Array.prototype
7575

@@ -78,6 +78,16 @@ angular.module('ui.scroll', [])
7878

7979
buffer.size = bufferSize
8080

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+
8191
# inserts wrapped element in the buffer
8292
# the first argument is either operation keyword (see below) or a number for operation 'insert'
8393
# 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', [])
113123
buffer.splice buffer.indexOf(arg1), 1
114124
removeElementAnimated arg1
115125

126+
127+
minIndex = Number.MAX_VALUE
128+
maxIndex = Number.MIN_VALUE
129+
116130
reset = ->
117131
buffer.eof = false
118132
buffer.bof = false
119133
buffer.first = origin
120134
buffer.next = origin
121135
buffer.localMinIndex = origin
122136

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+
123156
# clears the buffer
124157
buffer.clear = ->
125158
buffer.remove(0, buffer.length)
126159
reset()
127160

128161
reset()
129162

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-
145163
buffer
146164

147165
Padding = (template) ->
@@ -160,15 +178,15 @@ angular.module('ui.scroll', [])
160178
result
161179

162180

163-
Viewport = (buffer, element, controllers, padding) ->
181+
Viewport = (buffer, element, controllers, attrs) ->
164182

165183
viewport = if controllers[0] and controllers[0].viewport then controllers[0].viewport else angular.element(window)
166184
viewport.css({'overflow-y': 'auto', 'display': 'block'})
167185

168186
topPadding = null
169187
bottomPadding = null
170188

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
172190

173191
viewport.createPaddingElements = (template) ->
174192
topPadding = new Padding template
@@ -195,7 +213,7 @@ angular.module('ui.scroll', [])
195213
viewport.clipBottom = ->
196214
# clip the invisible items off the bottom
197215
overage = 0
198-
overageBottom = viewport.outerHeight() + viewport.averageItemHeight * (buffer.size)
216+
overageBottom = viewport.bottomVisiblePos() + viewport.averageItemHeight * (buffer.size)
199217
for i in [buffer.length-1..0]
200218
item = buffer[i]
201219
if item.element.offset().top > overageBottom
@@ -213,7 +231,7 @@ angular.module('ui.scroll', [])
213231
# clip the invisible items off the top
214232
overage = 0
215233
heightIncrement = 0
216-
overageTop = (-1) * viewport.averageItemHeight * buffer.size
234+
overageTop = viewport.topVisiblePos() - viewport.averageItemHeight * buffer.size
217235
for item in buffer
218236
if item.element.offset().top < overageTop
219237
heightIncrement += item.element.outerHeight()
@@ -224,17 +242,34 @@ angular.module('ui.scroll', [])
224242
buffer.remove(0, overage)
225243
buffer.first += overage
226244

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 = ->
228262
return if not buffer.length
229263
viewport.averageItemHeight = (buffer[buffer.length-1].element.offset().top +
230264
buffer[buffer.length-1].element.outerHeight(true) -
231265
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 = ->
232270
minIndex = buffer.minIndex()
233-
topPadding.height (buffer.first - minIndex.value) * viewport.averageItemHeight
234271
if minIndex.offset
235272
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
238273

239274
viewport.adjustScrollTop = (height) ->
240275
paddingHeight = topPadding.height() - height
@@ -282,15 +317,11 @@ angular.module('ui.scroll', [])
282317
adjustBuffer()
283318

284319
this.append = (newItems) ->
285-
for item in newItems
286-
++buffer.next
287-
buffer.insert 'append', item
320+
buffer.append newItems
288321
adjustBuffer()
289322

290323
this.prepend = (newItems) ->
291-
for item in newItems.reverse()
292-
--buffer.first
293-
buffer.insert 'prepend', item
324+
buffer.prepend newItems
294325
adjustBuffer()
295326

296327
setTopVisible = if $attr.topVisible then $parse($attr.topVisible).assign else ->
@@ -354,7 +385,7 @@ angular.module('ui.scroll', [])
354385

355386
pending = []
356387

357-
buffer = new Buffer(itemName, $scope, linker, datasource, bufferSize)
388+
buffer = new Buffer(itemName, $scope, linker, bufferSize)
358389

359390
viewport = new Viewport(buffer, element, controllers, $attr)
360391

@@ -456,6 +487,8 @@ angular.module('ui.scroll', [])
456487
adjustBuffer rid
457488
else
458489
viewport.adjustPadding()
490+
if not pending.length
491+
viewport.syncDatasource datasource
459492

460493
keepFetching
461494

@@ -490,12 +523,10 @@ angular.module('ui.scroll', [])
490523
fetch(rid)
491524

492525
fetch = (rid) ->
493-
#log "Running fetch... #{{true:'bottom', false: 'top'}[direction]} pending #{pending.length}"
494526
if pending[0] # scrolling down
495527
if buffer.length && !viewport.shouldLoadBottom()
496528
adjustBufferAfterFetch rid
497529
else
498-
#log "appending... requested #{bufferSize} records starting from #{next}"
499530
datasource.get buffer.next, bufferSize,
500531
(result) ->
501532
return if (rid and rid isnt ridActual) or $scope.$$destroyed
@@ -504,20 +535,13 @@ angular.module('ui.scroll', [])
504535
#log 'eof is reached'
505536
if result.length > 0
506537
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()
515540
adjustBufferAfterFetch rid
516541
else
517542
if buffer.length && !viewport.shouldLoadTop()
518543
adjustBufferAfterFetch rid
519544
else
520-
#log "prepending... requested #{size} records starting from #{start}"
521545
datasource.get buffer.first-bufferSize, bufferSize,
522546
(result) ->
523547
return if (rid and rid isnt ridActual) or $scope.$$destroyed
@@ -526,11 +550,8 @@ angular.module('ui.scroll', [])
526550
#log 'bof is reached'
527551
if result.length > 0
528552
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()
534555
adjustBufferAfterFetch rid
535556

536557
# events and bindings

0 commit comments

Comments
 (0)