git ssb

16+

Dominic / patchbay



Tree: fa60719a35f4fbc95fb5369409abb9b46abf1b5a

Files: fa60719a35f4fbc95fb5369409abb9b46abf1b5a / app / html / scroller.js

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

Built with git-ssb-web