Files: c1a1dc7a8dc3f88bd242e418cb5715798385f4e4 / app / html / scroller.js
2179 bytesRaw
1 | const nest = require('depnest') |
2 | const { h } = require('mutant') |
3 | |
4 | exports.gives = nest('app.html.scroller') |
5 | |
6 | exports.create = function (api) { |
7 | return nest('app.html.scroller', Scroller) |
8 | |
9 | function Scroller (opts = {}) { |
10 | const { prepend, content = null, append, classList = [], className = '', title = '', scrollIntoView } = opts |
11 | |
12 | const contentSection = h('section.content', { title: '' }, content) |
13 | |
14 | const container = h('Scroller', |
15 | { |
16 | classList, |
17 | className, |
18 | title, |
19 | style: { 'overflow-y': 'scroll', 'overflow-x': 'auto' }, |
20 | intersectionBindingViewport: { rootMargin: '1000px' } // mutant magic |
21 | // TODO (watch for breaks e.g. stuff stops updating after scrolling) |
22 | }, |
23 | [ |
24 | prepend ? h('section.top', prepend) : null, |
25 | contentSection, |
26 | append ? h('section.bottom', append) : null |
27 | ] |
28 | ) |
29 | |
30 | container.scroll = keyscroll(contentSection, scrollIntoView) |
31 | |
32 | return { |
33 | content: contentSection, |
34 | container |
35 | } |
36 | } |
37 | } |
38 | |
39 | function keyscroll (content, scrollIntoView = false) { |
40 | var curMsgEl |
41 | |
42 | if (!content) return () => {} |
43 | |
44 | content.addEventListener('click', onActivateChild, false) |
45 | content.addEventListener('focus', onActivateChild, true) |
46 | |
47 | function onActivateChild (ev) { |
48 | for (var el = ev.target; el; el = el.parentNode) { |
49 | if (el.parentNode === content) { |
50 | curMsgEl = el |
51 | return |
52 | } |
53 | } |
54 | } |
55 | |
56 | return function scroll (d) { |
57 | const child = (!curMsgEl || d === 'first') ? content.firstChild |
58 | : (!curMsgEl || d === 'last') ? content.lastChild |
59 | : d < 0 ? curMsgEl.previousElementSibling || content.firstChild |
60 | : d > 0 ? curMsgEl.nextElementSibling || content.lastChild |
61 | : curMsgEl |
62 | selectChild(child) |
63 | |
64 | return curMsgEl |
65 | } |
66 | |
67 | function selectChild (el) { |
68 | if (!el) { return } |
69 | |
70 | if (scrollIntoView) { |
71 | if (!el.scrollIntoViewIfNeeded && !el.scrollIntoView) return |
72 | ;(el.scrollIntoViewIfNeeded || el.scrollIntoView).call(el) |
73 | } else { |
74 | content.parentElement.scrollTop = el.offsetTop - content.parentElement.offsetTop - 10 |
75 | } |
76 | |
77 | if (el.focus) el.focus() |
78 | curMsgEl = el |
79 | } |
80 | } |
81 |
Built with git-ssb-web