Files: b2886f60b5b31141643c0ea134c62b9e8e0db8e2 / lib / pull-scroll.js
3569 bytesRaw
1 | // FROM: https://raw.githubusercontent.com/dominictarr/pull-scroll/master/index.js |
2 | var pull = require('pull-stream') |
3 | var Pause = require('pull-pause') |
4 | var isVisible = require('is-visible').isVisible |
5 | |
6 | var next = 'undefined' === typeof setImmediate ? setTimeout : setImmediate |
7 | |
8 | function 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 | |
15 | function isTop (scroller, buffer) { |
16 | return scroller.scrollTop <= (buffer || 0) |
17 | } |
18 | |
19 | function 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 | |
32 | function 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 | |
37 | function 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 | |
54 | function 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 | |
61 | var buffer = 1000 |
62 | module.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