Commit 0c32ba4ecf1c98ab797d92daa8ee0bfa0f1f4fa5
fork pull-scroll to fix under-filling and over-resuming issues
Matt McKegg committed on 6/13/2017, 4:52:06 AMParent: 333b18e1d9320cccf712a715185128a0b3c40eaf
Files changed
lib/pull-scroll.js | added |
modules/feed/html/rollup.js | changed |
modules/page/html/render/search.js | changed |
package.json | changed |
lib/pull-scroll.js | |||
---|---|---|---|
@@ -1,0 +1,117 @@ | |||
1 … | +// forked because of weird non-filling and over-resuming problems | ||
2 … | +// should really PR this, but Dominic might not accept it :D | ||
3 … | + | ||
4 … | +var pull = require('pull-stream') | ||
5 … | +var Pause = require('pull-pause') | ||
6 … | +var Obv = require('obv') | ||
7 … | + | ||
8 … | +var next = 'undefined' === typeof setImmediate ? setTimeout : setImmediate | ||
9 … | +var buffer = Math.max(window.innerHeight * 2, 1000) | ||
10 … | + | ||
11 … | +var u = require('pull-scroll/utils'), | ||
12 … | + assertScrollable = u.assertScrollable, | ||
13 … | + isEnd = u.isEnd, | ||
14 … | + isVisible = u.isVisible | ||
15 … | + | ||
16 … | +module.exports = Scroller | ||
17 … | + | ||
18 … | + | ||
19 … | +function Scroller(scroller, content, render, isPrepend, isSticky, cb) { | ||
20 … | + assertScrollable(scroller) | ||
21 … | + var obv = Obv() | ||
22 … | + | ||
23 … | + //if second argument is a function, | ||
24 … | + //it means the scroller and content elements are the same. | ||
25 … | + if('function' === typeof content) { | ||
26 … | + cb = isSticky | ||
27 … | + isPrepend = render | ||
28 … | + render = content | ||
29 … | + content = scroller | ||
30 … | + } | ||
31 … | + | ||
32 … | + if(!cb) cb = function (err) { if(err) throw err } | ||
33 … | + | ||
34 … | + scroller.addEventListener('scroll', scroll) | ||
35 … | + var pause = Pause(function () {}) | ||
36 … | + var queue = [] | ||
37 … | + | ||
38 … | + //apply some changes to the dom, but ensure that | ||
39 … | + //`element` is at the same place on screen afterwards. | ||
40 … | + | ||
41 … | + function add () { | ||
42 … | + if(queue.length) { | ||
43 … | + var m = queue.shift() | ||
44 … | + var r = render(m) | ||
45 … | + append(scroller, content, r, isPrepend, isSticky) | ||
46 … | + obv.set(queue.length) | ||
47 … | + } | ||
48 … | + } | ||
49 … | + | ||
50 … | + function scroll (ev) { | ||
51 … | + if(isEnd(scroller, buffer, isPrepend)) { | ||
52 … | + pause.resume() | ||
53 … | + } | ||
54 … | + } | ||
55 … | + | ||
56 … | + pause.pause() | ||
57 … | + | ||
58 … | + //wait until the scroller has been added to the document | ||
59 … | + next(function next () { | ||
60 … | + if(scroller.parentElement) pause.resume() | ||
61 … | + else setTimeout(next, 100) | ||
62 … | + }) | ||
63 … | + | ||
64 … | + var stream = pull( | ||
65 … | + pause, | ||
66 … | + pull.drain(function (e) { | ||
67 … | + queue.push(e) | ||
68 … | + obv.set(queue.length) | ||
69 … | + | ||
70 … | + if(content.clientHeight < window.innerHeight) | ||
71 … | + add() | ||
72 … | + | ||
73 … | + if (isVisible(content)) { | ||
74 … | + if (isEnd(scroller, buffer, isPrepend)) | ||
75 … | + add() | ||
76 … | + } | ||
77 … | + | ||
78 … | + if(queue.length > 5) | ||
79 … | + pause.pause() | ||
80 … | + | ||
81 … | + }, function (err) { | ||
82 … | + if(err) console.error(err) | ||
83 … | + cb ? cb(err) : console.error(err) | ||
84 … | + }) | ||
85 … | + ) | ||
86 … | + | ||
87 … | + stream.visible = add | ||
88 … | + stream.observ = obv | ||
89 … | + return stream | ||
90 … | +} | ||
91 … | + | ||
92 … | + | ||
93 … | +function append(scroller, list, el, isPrepend, isSticky) { | ||
94 … | + if(!el) return | ||
95 … | + var s = scroller.scrollHeight | ||
96 … | + var st = scroller.scrollTop | ||
97 … | + if(isPrepend && list.firstChild) | ||
98 … | + list.insertBefore(el, list.firstChild) | ||
99 … | + else | ||
100 … | + list.appendChild(el) | ||
101 … | + | ||
102 … | + //scroll down by the height of the thing added. | ||
103 … | + //if it added to the top (in non-sticky mode) | ||
104 … | + //or added it to the bottom (in sticky mode) | ||
105 … | + if(isPrepend !== isSticky) { | ||
106 … | + var d = (scroller.scrollHeight - s) | ||
107 … | + var before = scroller.scrollTop | ||
108 … | + //check whether the browser has moved the scrollTop for us. | ||
109 … | + //if you add an element that is not scrolled into view | ||
110 … | + //it no longer bumps the view down! but this check is still needed | ||
111 … | + //for firefox. | ||
112 … | + //this seems to be the behavior in recent chrome (also electron) | ||
113 … | + if(st === scroller.scrollTop) { | ||
114 … | + scroller.scrollTop = scroller.scrollTop + d | ||
115 … | + } | ||
116 … | + } | ||
117 … | +} |
modules/feed/html/rollup.js | ||
---|---|---|
@@ -9,9 +9,9 @@ | ||
9 | 9 … | var pull = require('pull-stream') |
10 | 10 … | var nest = require('depnest') |
11 | 11 … | |
12 | 12 … | var onceTrue = require('mutant/once-true') |
13 | -var Scroller = require('pull-scroll') | |
13 … | +var Scroller = require('../../../lib/pull-scroll') | |
14 | 14 … | |
15 | 15 … | exports.needs = nest({ |
16 | 16 … | 'message.html': { |
17 | 17 … | render: 'first', |
modules/page/html/render/search.js | ||
---|---|---|
@@ -1,7 +1,7 @@ | ||
1 | 1 … | const { h, Struct, Value, when, computed } = require('mutant') |
2 | 2 … | const pull = require('pull-stream') |
3 | -const Scroller = require('pull-scroll') | |
3 … | +const Scroller = require('../../../../lib/pull-scroll') | |
4 | 4 … | const TextNodeSearcher = require('text-node-searcher') |
5 | 5 … | const whitespace = /\s+/ |
6 | 6 … | const pullAbortable = require('pull-abortable') |
7 | 7 … | var nest = require('depnest') |
package.json | ||
---|---|---|
@@ -27,8 +27,9 @@ | ||
27 | 27 … | "level": "~1.7.0", |
28 | 28 … | "micro-css": "^2.0.0", |
29 | 29 … | "mutant": "^3.20.1", |
30 | 30 … | "mutant-pull-reduce": "^1.1.0", |
31 … | + "obv": "0.0.1", | |
31 | 32 … | "patchcore": "~1.0.2", |
32 | 33 … | "patchwork-gatherings": "^1.0.2", |
33 | 34 … | "pull-abortable": "^4.1.0", |
34 | 35 … | "pull-defer": "^0.2.2", |
Built with git-ssb-web