Commit 02f1d746a759d2cd6c1df4f041d77781e6476103
fix pull-scroll in decent too
Ev Bogue committed on 4/13/2017, 9:06:03 PMParent: 44c55621a7eaeae2d584e97f32151bd6cc2b8225
Files changed
build/index.html | ||
---|---|---|
The diff is too large to show. Use a local git client to view these changes. Old file size: 737351 bytes New file size: 737402 bytes |
client/modules/channel.js | ||
---|---|---|
@@ -1,8 +1,8 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | var u = require('../util') |
3 | 3 … | var pull = require('pull-stream') |
4 | -var Scroller = require('pull-scroll') | |
4 … | +var Scroller = require('../pull-scroll') | |
5 | 5 … | var mfr = require('map-filter-reduce') |
6 | 6 … | |
7 | 7 … | exports.needs = { |
8 | 8 … | message_render: 'first', |
client/modules/feed.js | ||
---|---|---|
@@ -1,6 +1,6 @@ | ||
1 | 1 … | var ref = require('ssb-ref') |
2 | -var Scroller = require('pull-scroll') | |
2 … | +var Scroller = require('../pull-scroll') | |
3 | 3 … | var h = require('hyperscript') |
4 | 4 … | var pull = require('pull-stream') |
5 | 5 … | var u = require('../util') |
6 | 6 … |
client/modules/identify.js | ||
---|---|---|
@@ -1,8 +1,8 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | var u = require('../util') |
3 | 3 … | var pull = require('pull-stream') |
4 | -var Scroller = require('pull-scroll') | |
4 … | +var Scroller = require('../pull-scroll') | |
5 | 5 … | var id = require('../keys').id |
6 | 6 … | |
7 | 7 … | exports.needs = { |
8 | 8 … | publish: 'first' |
client/modules/key.js | ||
---|---|---|
@@ -1,8 +1,8 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | var u = require('../util') |
3 | 3 … | var pull = require('pull-stream') |
4 | -var Scroller = require('pull-scroll') | |
4 … | +var Scroller = require('../pull-scroll') | |
5 | 5 … | |
6 | 6 … | exports.gives = { |
7 | 7 … | screen_view: true |
8 | 8 … | } |
client/modules/notifications.js | ||
---|---|---|
@@ -1,9 +1,9 @@ | ||
1 | 1 … | |
2 | 2 … | var h = require('hyperscript') |
3 | 3 … | var u = require('../util') |
4 | 4 … | var pull = require('pull-stream') |
5 | -var Scroller = require('pull-scroll') | |
5 … | +var Scroller = require('../pull-scroll') | |
6 | 6 … | var paramap = require('pull-paramap') |
7 | 7 … | var plugs = require('../plugs') |
8 | 8 … | var cont = require('cont') |
9 | 9 … | var ref = require('ssb-ref') |
client/modules/private.js | ||
---|---|---|
@@ -1,9 +1,9 @@ | ||
1 | 1 … | |
2 | 2 … | var h = require('hyperscript') |
3 | 3 … | var u = require('../util') |
4 | 4 … | var pull = require('pull-stream') |
5 | -var Scroller = require('pull-scroll') | |
5 … | +var Scroller = require('../pull-scroll') | |
6 | 6 … | var ref = require('ssb-ref') |
7 | 7 … | |
8 | 8 … | function map(ary, iter) { |
9 | 9 … | if(Array.isArray(ary)) return ary.map(iter) |
client/modules/profile-edit.js | ||
---|---|---|
@@ -1,8 +1,8 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | var u = require('../util') |
3 | 3 … | var pull = require('pull-stream') |
4 | -var Scroller = require('pull-scroll') | |
4 … | +var Scroller = require('../pull-scroll') | |
5 | 5 … | var id = require('../keys').id |
6 | 6 … | |
7 | 7 … | exports.needs = { |
8 | 8 … | publish: 'first', |
client/modules/public.js | ||
---|---|---|
@@ -1,8 +1,8 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | var u = require('../util') |
3 | 3 … | var pull = require('pull-stream') |
4 | -var Scroller = require('pull-scroll') | |
4 … | +var Scroller = require('../pull-scroll') | |
5 | 5 … | |
6 | 6 … | exports.needs = { |
7 | 7 … | message_render: 'first', |
8 | 8 … | message_compose: 'first', |
client/modules/search.js | ||
---|---|---|
@@ -1,8 +1,8 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | var u = require('../util') |
3 | 3 … | var pull = require('pull-stream') |
4 | -var Scroller = require('pull-scroll') | |
4 … | +var Scroller = require('../pull-scroll') | |
5 | 5 … | var TextNodeSearcher = require('text-node-searcher') |
6 | 6 … | |
7 | 7 … | exports.needs = { |
8 | 8 … | message_render: 'first', |
client/modules/thread.js | ||
---|---|---|
@@ -3,9 +3,9 @@ | ||
3 | 3 … | var sort = require('ssb-sort') |
4 | 4 … | var ref = require('ssb-ref') |
5 | 5 … | var h = require('hyperscript') |
6 | 6 … | var u = require('../util') |
7 | -var Scroller = require('pull-scroll') | |
7 … | +var Scroller = require('../pull-scroll') | |
8 | 8 … | var self_id = require('../keys').id |
9 | 9 … | |
10 | 10 … | function once (cont) { |
11 | 11 … | var ended = false |
client/pull-scroll/LICENSE | ||
---|---|---|
@@ -1,0 +1,22 @@ | ||
1 … | +Copyright (c) 2016 Dominic Tarr | |
2 … | + | |
3 … | +Permission is hereby granted, free of charge, | |
4 … | +to any person obtaining a copy of this software and | |
5 … | +associated documentation files (the "Software"), to | |
6 … | +deal in the Software without restriction, including | |
7 … | +without limitation the rights to use, copy, modify, | |
8 … | +merge, publish, distribute, sublicense, and/or sell | |
9 … | +copies of the Software, and to permit persons to whom | |
10 … | +the Software is furnished to do so, | |
11 … | +subject to the following conditions: | |
12 … | + | |
13 … | +The above copyright notice and this permission notice | |
14 … | +shall be included in all copies or substantial portions of the Software. | |
15 … | + | |
16 … | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
17 … | +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |
18 … | +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
19 … | +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR | |
20 … | +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
21 … | +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
22 … | +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
client/pull-scroll/README.md | ||
---|---|---|
@@ -1,0 +1,93 @@ | ||
1 … | +# pull-scroll | |
2 … | + | |
3 … | +pull-stream to a infinite scrolling web pane. | |
4 … | + | |
5 … | +streams are for programatically dealing with data that | |
6 … | +arrives or is processed over time. Many applications | |
7 … | +also have features they call "streams", or views | |
8 … | +that may contain a large number of items, | |
9 … | +if you just keep scrolling down? | |
10 … | + | |
11 … | +pull-scroll is the simplest way to join these concepts, | |
12 … | +you can take a pull-stream of content, attach it to a | |
13 … | +scrolling element, and the scroller sets the back pressure. | |
14 … | + | |
15 … | +when the element is filled, back pressure kicks in, | |
16 … | +and when you scroll to the end, it is released, and more data flows in. | |
17 … | + | |
18 … | +pull-scroll can be used for both double and single ended content streams. | |
19 … | + | |
20 … | +## example | |
21 … | + | |
22 … | +``` js | |
23 … | +var Scroller = require('pull-scroll') | |
24 … | +var pull = require('pull-stream') | |
25 … | +var h = require('hyperscript') | |
26 … | + | |
27 … | +var content = h('div') | |
28 … | +var scroller = h('div', { | |
29 … | + style: { | |
30 … | + //must set overflow-y to scroll for this to work. | |
31 … | + 'overflow-y': 'scroll', | |
32 … | + //and cause this element to not stretch. | |
33 … | + //this can also be achived using flexbox column. | |
34 … | + position: 'fixed', bottom:'0px', top: '0px', | |
35 … | + width: '600px' | |
36 … | + } | |
37 … | + }, content) | |
38 … | + | |
39 … | + //provide a render function that returns an html element. | |
40 … | + function render (n) { | |
41 … | + return h('h1', n.toString()) | |
42 … | + } | |
43 … | + | |
44 … | + pull( | |
45 … | + pull.infinite(), | |
46 … | + Scroller(scroller, content, render) | |
47 … | + ) | |
48 … | + | |
49 … | +document.body.appendChild(scroller) | |
50 … | +``` | |
51 … | + | |
52 … | +you can have attach two Scrollers to an element, one for scrolling up | |
53 … | +and one for scrolling down. (thus, a two way infinite scroller) | |
54 … | + | |
55 … | +see [example here](https://github.com/dominictarr/patchbay/blob/master/modules/public.js#L24-L32) | |
56 … | + | |
57 … | +## api | |
58 … | + | |
59 … | +### Scroller(scrollable, container, render, isPrepend, isSticky, cb) => Sink | |
60 … | + | |
61 … | +Create a pull-stream sink where the back pressure is controlled by the scrolling of the element. | |
62 … | +`scrollable` needs to be an element which can scroll, and `container` | |
63 … | +is an optional child (otherwise elements will be added directly to `scrollable`) | |
64 … | + | |
65 … | +`render` is a function that takes stream items and returns an html element. | |
66 … | + | |
67 … | +If `isPrepend` is true, elements will be added before the first child of container, | |
68 … | +if it is false, they will be appended. | |
69 … | + | |
70 … | +If `isSticky` is true, `scrollable` will be scrolled into position after adding an element. | |
71 … | +this will make more elements come automatically, untill you scroll away. | |
72 … | +If `isSticky` is false, new elements will extend the container, but not be scrolled into positon, | |
73 … | +this means the scroll will only be adjusted as the user scrolls. | |
74 … | + | |
75 … | +If the user is scrolling to read old data (i.e. scrolling down on twitter, or up in the terminal) | |
76 … | +then use `isSticky=false`. If the user is scrolled to the end to get new data, | |
77 … | +(i.e. scrolling to the top on twitter, or the bottom in the terminal) | |
78 … | +then use `isSticky=true`. | |
79 … | + | |
80 … | +`cb` is an optional callback used only for error handling. | |
81 … | +This defaults to | |
82 … | +```js | |
83 … | +function (err) { if(err) console.error(err) } | |
84 … | +``` | |
85 … | + | |
86 … | +## License | |
87 … | + | |
88 … | +MIT | |
89 … | + | |
90 … | + | |
91 … | + | |
92 … | + | |
93 … | + |
client/pull-scroll/examples/README.md | ||
---|---|---|
@@ -1,0 +1,19 @@ | ||
1 … | + | |
2 … | +# run examples in electron | |
3 … | + | |
4 … | +``` | |
5 … | +npm install electron-prebuilt electro -g | |
6 … | +electro examples/simple.js | |
7 … | +``` | |
8 … | +[electro](https://github.com/dominictarr/electro) is my electron wrapper | |
9 … | +that lets you just run a single js file and pipe to it via stdio. | |
10 … | + | |
11 … | + | |
12 … | +# run examples in a browser via browserify | |
13 … | + | |
14 … | +``` | |
15 … | +npm install browserify indexhtmlify -g | |
16 … | + | |
17 … | +browserify examples/simple.js | indexhtmlify > index.html | |
18 … | +``` | |
19 … | +then open that in your prefured web browser! |
client/pull-scroll/examples/columns.js | ||
---|---|---|
@@ -1,0 +1,85 @@ | ||
1 … | +var h = require('hyperscript') | |
2 … | +var o = require('observable') | |
3 … | +var pull = require('pull-stream') | |
4 … | +var Pause = require('pull-pause') | |
5 … | + | |
6 … | +var Scroller = require('../') | |
7 … | + | |
8 … | +var c = o.value() | |
9 … | +var v = o.value() | |
10 … | + | |
11 … | +var check = h('input', {type: 'checkbox'}) | |
12 … | +var sticky = o.input(check, 'checked') | |
13 … | +var panel | |
14 … | +document.body.appendChild( | |
15 … | + panel = h('div.screen', { | |
16 … | + style: { | |
17 … | + top: '0px', bottom: '0px', | |
18 … | + position: 'absolute', | |
19 … | + display: 'flex', | |
20 … | + 'flex-direction': 'row' | |
21 … | + } | |
22 … | + }, | |
23 … | + h('div', {style: {position: 'fixed', right: '20px', top: '20px'}}, | |
24 … | + c, '-', v, check, | |
25 … | + h('a', 'Create!', {href: '#', onclick: function () { | |
26 … | + panel.appendChild(createScroller()) | |
27 … | + }}) | |
28 … | + ) | |
29 … | + ) | |
30 … | +) | |
31 … | + | |
32 … | +//load below the screen bottom, so that normal reading is jankless. | |
33 … | + | |
34 … | +//user provided source stream | |
35 … | +function createSource (top) { | |
36 … | + return pull( | |
37 … | + pull.infinite(), | |
38 … | + pull.map(function (e) { | |
39 … | + c((c()||0)+1) | |
40 … | + return {random: e, count: c(), top: top} | |
41 … | + }), | |
42 … | + pull.asyncMap(function (e, cb) { | |
43 … | + var delay = 100 + 200*Math.random() | |
44 … | + setTimeout(function () { | |
45 … | + e.delay = delay | |
46 … | + cb(null, e) | |
47 … | + }, delay) | |
48 … | + }) | |
49 … | + ) | |
50 … | +} | |
51 … | + | |
52 … | +function render (e) { | |
53 … | + return h('h3', { | |
54 … | + style: {background: 'hsl('+Math.round(Math.random()*360) + ',100%,50%)' | |
55 … | + } | |
56 … | + }, h('pre', JSON.stringify(e, null, 2))) | |
57 … | +} | |
58 … | + | |
59 … | +function createScroller () { | |
60 … | + var scroller = SCROLLER = h('ol', { | |
61 … | + style: { | |
62 … | + 'flex-bias': 0, | |
63 … | + overflowY: 'scroll', | |
64 … | + overflow: 'auto', | |
65 … | + display: 'inline-block' | |
66 … | + } | |
67 … | + }) | |
68 … | + | |
69 … | + pull( | |
70 … | + createSource(true), | |
71 … | + Scroller(scroller, render, true, false) | |
72 … | + ) | |
73 … | + | |
74 … | + pull( | |
75 … | + createSource(false), | |
76 … | + Scroller(scroller, render, false, false) | |
77 … | + ) | |
78 … | + | |
79 … | + return h('div', {style: { | |
80 … | + display: 'flex', 'flex-bias': 0, | |
81 … | + 'flex-direction': 'column' | |
82 … | + }}, h('h1', 'scroller') , scroller) | |
83 … | +} | |
84 … | + | |
85 … | + |
client/pull-scroll/examples/simple.js | ||
---|---|---|
@@ -1,0 +1,37 @@ | ||
1 … | +var Scroller = require('../') | |
2 … | +var pull = require('pull-stream') | |
3 … | +var h = require('hyperscript') | |
4 … | + | |
5 … | +var content = h('div') | |
6 … | +var scroller = h('div', { | |
7 … | + style: { | |
8 … | + //must set overflow-y to scroll for this to work. | |
9 … | + 'overflow-y': 'scroll', | |
10 … | + //and cause this element to not stretch. | |
11 … | + //this can also be achived using flexbox column. | |
12 … | + position: 'fixed', bottom:'0px', top: '0px', | |
13 … | + 'margin-left': 'auto', | |
14 … | + 'margin-right': 'auto', | |
15 … | + width: '600px' | |
16 … | + } | |
17 … | + }, content) | |
18 … | + | |
19 … | + //provide a render function that returns an html element. | |
20 … | + function render (n) { | |
21 … | + return h('h1', n.toString()) | |
22 … | + } | |
23 … | + | |
24 … | + pull( | |
25 … | + pull.infinite(), | |
26 … | + Scroller(scroller, content, render) | |
27 … | + ) | |
28 … | + | |
29 … | +document.body.appendChild(scroller) | |
30 … | + | |
31 … | + | |
32 … | + | |
33 … | + | |
34 … | + | |
35 … | + | |
36 … | + | |
37 … | + |
client/pull-scroll/index.js | ||
---|---|---|
@@ -1,0 +1,100 @@ | ||
1 … | +var pull = require('pull-stream') | |
2 … | +var Pause = require('pull-pause') | |
3 … | + | |
4 … | +var next = 'undefined' === typeof setImmediate ? setTimeout : setImmediate | |
5 … | +var buffer = Math.max(window.innerHeight * 2, 1000) | |
6 … | + | |
7 … | +var u = require('./utils'), | |
8 … | + assertScrollable = u.assertScrollable, | |
9 … | + isEnd = u.isEnd, | |
10 … | + isFilled = u.isFilled, | |
11 … | + isVisible = u.isVisible, | |
12 … | + isScroll = u.isScroll | |
13 … | + | |
14 … | +module.exports = Scroller | |
15 … | + | |
16 … | +function Scroller(scroller, content, render, isPrepend, isSticky, cb) { | |
17 … | + assertScrollable(scroller) | |
18 … | + | |
19 … | + //if second argument is a function, | |
20 … | + //it means the scroller and content elements are the same. | |
21 … | + if('function' === typeof content) { | |
22 … | + cb = isSticky | |
23 … | + isPrepend = render | |
24 … | + render = content | |
25 … | + content = scroller | |
26 … | + } | |
27 … | + | |
28 … | + if(!cb) cb = function (err) { if(err) throw err } | |
29 … | + | |
30 … | + scroller.addEventListener('scroll', scroll) | |
31 … | + var pause = Pause(function () {}) | |
32 … | + var queue = [] | |
33 … | + | |
34 … | + //apply some changes to the dom, but ensure that | |
35 … | + //`element` is at the same place on screen afterwards. | |
36 … | + | |
37 … | + function add () { | |
38 … | + if(queue.length) { | |
39 … | + var m = queue.shift() | |
40 … | + var r = render(m) | |
41 … | + append(scroller, content, r, isPrepend, isSticky) | |
42 … | + } | |
43 … | + } | |
44 … | + | |
45 … | + function scroll (ev) { | |
46 … | + if(isEnd(scroller, buffer, isPrepend) || !isFilled(content)) { | |
47 … | + pause.resume() | |
48 … | + add() | |
49 … | + } | |
50 … | + } | |
51 … | + | |
52 … | + pause.pause() | |
53 … | + | |
54 … | + //wait until the scroller has been added to the document | |
55 … | + next(function next () { | |
56 … | + if(scroller.parentElement) pause.resume() | |
57 … | + else setTimeout(next, 100) | |
58 … | + }) | |
59 … | + | |
60 … | + var stream = pull( | |
61 … | + pause, | |
62 … | + pull.drain(function (e) { | |
63 … | + queue.push(e) | |
64 … | + //we don't know the scroll bar positions if it's display none | |
65 … | + //so we have to wait until it becomes visible again. | |
66 … | + if(!isVisible(content)) { | |
67 … | + if(content.children.length < 15) add() | |
68 … | + } | |
69 … | + else if(!isScroll(scroller)) add() | |
70 … | + else if(isEnd(scroller, buffer, isPrepend)) add() | |
71 … | + | |
72 … | + if(queue.length > 5) pause.pause() | |
73 … | + }, function (err) { | |
74 … | + if(err) console.error(err) | |
75 … | + cb ? cb(err) : console.error(err) | |
76 … | + }) | |
77 … | + ) | |
78 … | + | |
79 … | + stream.visible = add | |
80 … | + return stream | |
81 … | +} | |
82 … | + | |
83 … | + | |
84 … | +function append(scroller, list, el, isPrepend, isSticky) { | |
85 … | + if(!el) return | |
86 … | + var s = scroller.scrollHeight | |
87 … | + if(isPrepend && list.firstChild) | |
88 … | + list.insertBefore(el, list.firstChild) | |
89 … | + else | |
90 … | + list.appendChild(el) | |
91 … | + | |
92 … | + //scroll down by the height of the thing added. | |
93 … | + //if it added to the top (in non-sticky mode) | |
94 … | + //or added it to the bottom (in sticky mode) | |
95 … | + if(isPrepend !== isSticky) { | |
96 … | + var d = (scroller.scrollHeight - s) + 1 | |
97 … | + scroller.scrollTop = scroller.scrollTop + d | |
98 … | + } | |
99 … | +} | |
100 … | + |
client/pull-scroll/package.json | ||
---|---|---|
@@ -1,0 +1,23 @@ | ||
1 … | +{ | |
2 … | + "name": "pull-scroll", | |
3 … | + "description": "", | |
4 … | + "version": "0.3.4", | |
5 … | + "homepage": "https://github.com/dominictarr/pull-scroll", | |
6 … | + "repository": { | |
7 … | + "type": "git", | |
8 … | + "url": "git://github.com/dominictarr/pull-scroll.git" | |
9 … | + }, | |
10 … | + "dependencies": { | |
11 … | + "pull-pause": "0.0.0", | |
12 … | + "pull-stream": "^3.0.1" | |
13 … | + }, | |
14 … | + "devDependencies": { | |
15 … | + "hyperscript": "^2.0.2", | |
16 … | + "observable": "^2.1.4" | |
17 … | + }, | |
18 … | + "scripts": { | |
19 … | + "test": "set -e; for t in test/*.js; do node $t; done" | |
20 … | + }, | |
21 … | + "author": "Dominic Tarr <dominic.tarr@gmail.com> (http://dominictarr.com)", | |
22 … | + "license": "MIT" | |
23 … | +} |
client/pull-scroll/utils.js | ||
---|---|---|
@@ -1,0 +1,66 @@ | ||
1 … | + | |
2 … | +function assertScrollable(scroller) { | |
3 … | + var f = overflow(scroller) | |
4 … | + if(!/auto|scroll/.test(f)) | |
5 … | + throw new Error('scroller.style.overflowY must be scroll or auto, was:' + f + '!') | |
6 … | +} | |
7 … | + | |
8 … | +function isEnd(scroller, buffer, isPrepend) { | |
9 … | + //if the element is display none, don't read anything into it. | |
10 … | + return (isPrepend ? isTop : isBottom)(scroller, buffer) | |
11 … | +} | |
12 … | + | |
13 … | +function isFilled(content) { | |
14 … | + return ( | |
15 … | + !isVisible(content) | |
16 … | + //check if the scroller is not visible. | |
17 … | + // && content.getBoundingClientRect().height == 0 | |
18 … | + //and has children. if there are no children, | |
19 … | + //it might be size zero because it hasn't started yet. | |
20 … | + && content.children.length > 10 | |
21 … | + //&& !isVisible(scroller) | |
22 … | + ) | |
23 … | +} | |
24 … | + | |
25 … | +function isVisible (el) { | |
26 … | + var style = getComputedStyle(el) | |
27 … | + return style.display === 'none' || style.visibility === 'hidden' | |
28 … | +} | |
29 … | + | |
30 … | +//test wether element has an active scroll bar. | |
31 … | +//(element needs to be visible for this to work) | |
32 … | + | |
33 … | +function isScroll (el) { | |
34 … | + return el.scrollHeight != el.clientHeight | |
35 … | +} | |
36 … | + | |
37 … | + | |
38 … | +module.exports = { | |
39 … | + assertScrollable: assertScrollable, | |
40 … | + isEnd: isEnd, | |
41 … | + isFilled: isFilled, | |
42 … | + isVisible: isVisible, | |
43 … | + isScroll: isScroll | |
44 … | +} | |
45 … | + | |
46 … | + | |
47 … | +// 'private' functions | |
48 … | + | |
49 … | +function overflow (el) { | |
50 … | + return el.style.overflowY || el.style.overflow || (function () { | |
51 … | + var style = getComputedStyle(el) | |
52 … | + return style.overflowY || el.style.overflow | |
53 … | + })() | |
54 … | +} | |
55 … | + | |
56 … | +function isTop (scroller, buffer) { | |
57 … | + return scroller.scrollTop <= (buffer || 0) | |
58 … | +} | |
59 … | + | |
60 … | +function isBottom (scroller, buffer) { | |
61 … | + var rect = scroller.getBoundingClientRect() | |
62 … | + var topmax = scroller.scrollTopMax || (scroller.scrollHeight - rect.height) | |
63 … | + return scroller.scrollTop >= | |
64 … | + + ((topmax) - (buffer || 0)) | |
65 … | +} | |
66 … | + |
Built with git-ssb-web