git ssb

0+

alanz / patchwork



forked from Matt McKegg / patchwork

Tree: 9744d260b89e1e2afac37b36c0973c99040adefd

Files: 9744d260b89e1e2afac37b36c0973c99040adefd / lib / pull-scroll.js

3569 bytesRaw
1// FROM: https://raw.githubusercontent.com/dominictarr/pull-scroll/master/index.js
2var pull = require('pull-stream')
3var Pause = require('pull-pause')
4var isVisible = require('is-visible').isVisible
5
6var next = 'undefined' === typeof setImmediate ? setTimeout : setImmediate
7
8function isBottom (scroller, buffer) {
9 var rect = scroller.getBoundingClientRect()
10 var topmax = scroller.scrollTopMax || (scroller.scrollHeight - rect.height)
11 return scroller.scrollTop >=
12 + ((topmax) - (buffer || 0))
13}
14
15function isTop (scroller, buffer) {
16 return scroller.scrollTop <= (buffer || 0)
17}
18
19function isFilled(content) {
20 return (
21 !isVisible(content)
22 //check if the scroller is not visible.
23 // && content.getBoundingClientRect().height == 0
24 //and has children. if there are no children,
25 //it might be size zero because it hasn't started yet.
26// &&
27 && content.children.length > 20
28 //&& !isVisible(scroller)
29 )
30}
31
32function isEnd(scroller, buffer, top) {
33 //if the element is display none, don't read anything into it.
34 return (top ? isTop : isBottom)(scroller, buffer)
35}
36
37function append(scroller, list, el, top, sticky) {
38 if(!el) return
39 var s = scroller.scrollHeight
40 if(top && list.firstChild)
41 list.insertBefore(el, list.firstChild)
42 else
43 list.appendChild(el)
44
45 //scroll down by the height of the thing added.
46 //if it added to the top (in non-sticky mode)
47 //or added it to the bottom (in sticky mode)
48 if(top !== sticky) {
49 var st = list.scrollTop, d = (scroller.scrollHeight - s) + 1
50 scroller.scrollTop = scroller.scrollTop + d
51 }
52}
53
54function overflow (el) {
55 return el.style.overflowY || el.style.overflow || (function () {
56 var style = getComputedStyle(el)
57 return style.overflowY || el.style.overflow
58 })()
59}
60
61var buffer = 1000
62module.exports = function Scroller(scroller, content, render, top, sticky, cb) {
63 //if second argument is a function,
64 //it means the scroller and content elements are the same.
65 if('function' === typeof content) {
66 cb = sticky
67 top = render
68 render = content
69 content = scroller
70 }
71
72 if(!cb) cb = function (err) { if(err) throw err }
73
74 var f = overflow(scroller)
75 if(!/auto|scroll/.test(f))
76 throw new Error('scroller.style.overflowY must be scroll or auto, was:' + f + '!')
77 scroller.addEventListener('scroll', scroll)
78 var pause = Pause(function () {}), queue = []
79
80 //apply some changes to the dom, but ensure that
81 //`element` is at the same place on screen afterwards.
82
83 function add () {
84 if(queue.length)
85 append(scroller, content, render(queue.shift()), top, sticky)
86 }
87
88 function scroll (ev) {
89 if (isEnd(scroller, buffer, top) || isFilled(content)) {
90 pause.resume()
91 add()
92 }
93 }
94
95 // pause.pause()
96 //
97 // //wait until the scroller has been added to the document
98 // next(function next () {
99 // if(scroller.parentElement) pause.resume()
100 // else setTimeout(next, 100)
101 // })
102
103 var stream = pull(
104 pause,
105 pull.drain(function (e) {
106 queue.push(e)
107 //we don't know the scroll bar positions if it's display none
108 //so we have to wait until it becomes visible again.
109 if(!isVisible(content)) {
110 if(content.children.length < 20) add()
111 }
112 else if(isEnd(scroller, buffer, top)) add()
113
114 if(queue.length > 10) pause.pause()
115 }, function (err) {
116 scroller.removeEventListener('scroll', scroll)
117 if(err) console.error(err)
118 cb ? cb(err) : console.error(err)
119 })
120 )
121
122 stream.visible = add
123
124 return stream
125
126}
127

Built with git-ssb-web