git ssb

16+

Dominic / patchbay



Tree: fae873d9c5a0a2c689203fc9851d13b2f3c63e3a

Files: fae873d9c5a0a2c689203fc9851d13b2f3c63e3a / modules_core / tabs.js

5738 bytesRaw
1const Tabs = require('hypertabs')
2const h = require('../h')
3const keyscroll = require('../keyscroll')
4const open = require('open-external')
5
6function ancestor (el) {
7 if(!el) return
8 if(el.tagName !== 'A') return ancestor(el.parentElement)
9 return el
10}
11
12exports.needs = {
13 screen_view: 'first',
14 search_box: 'first',
15 menu: 'first',
16 external_confirm:'first'
17}
18
19exports.gives = 'screen_view'
20
21exports.create = function (api) {
22 return function (path) {
23 if(path !== 'tabs') return
24
25 function setSelected (indexes) {
26 var ids = indexes.map(function (index) {
27 return tabs.get(index).id
28 })
29 if(search)
30 if(ids.length > 1)
31 search.value = 'split('+ids.join(',')+')'
32 else
33 search.value = ids[0]
34 }
35
36 var search
37 var tabs = Tabs(setSelected)
38
39 search = api.search_box(function (path, change) {
40
41 if(tabs.has(path)) {
42 tabs.select(path)
43 return true
44 }
45 var el = api.screen_view(path)
46
47 if(el) {
48 if(!el.title) el.title = path
49 el.scroll = keyscroll(el.querySelector('.scroller__content'))
50 tabs.add(el, change)
51 // localStorage.openTabs = JSON.stringify(tabs.tabs)
52 return change
53 }
54 })
55
56 //reposition hypertabs menu to inside a container...
57 tabs.insertBefore(h('div.header.row', [
58 h('div.header__tabs.row', tabs.firstChild), //tabs
59 h('div.header__search.row.end', [
60 h('div', search),
61 api.menu()
62 ])
63 ]),
64 tabs.firstChild)
65 // tabs.insertBefore(search, tabs.firstChild.nextSibling)
66
67 var saved = []
68 // try { saved = JSON.parse(localStorage.openTabs) }
69 // catch (_) { }
70
71 if(!saved || saved.length < 3)
72 saved = ['/public', '/private', '/notifications', '/data']
73
74 saved.forEach(function (path) {
75 var el = api.screen_view(path)
76 if(!el) return
77 el.id = el.id || path
78 if (!el) return
79 el.scroll = keyscroll(el.querySelector('.scroller__content'))
80 if(el) tabs.add(el, false, false)
81 })
82
83 tabs.select(0)
84
85 //handle link clicks
86 window.onclick = function (ev) {
87 var link = ancestor(ev.target)
88 if(!link) return
89 var path = link.hash.substring(1)
90
91 ev.preventDefault()
92 ev.stopPropagation()
93
94 //let the application handle this link
95 if (link.getAttribute('href') === '#') return
96
97 //open external links.
98 //this ought to be made into something more runcible
99 if(link.href && open.isExternal(link.href)) return api.external_confirm(link.href)
100
101 if(tabs.has(path))
102 return tabs.select(path, !ev.ctrlKey, !!ev.shiftKey)
103
104 var el = api.screen_view(path)
105 if(el) {
106 el.id = el.id || path
107 el.scroll = keyscroll(el.querySelector('.scroller__content'))
108 tabs.add(el, !ev.ctrlKey, !!ev.shiftKey)
109 // localStorage.openTabs = JSON.stringify(tabs.tabs)
110 }
111
112 return false
113 }
114
115 window.addEventListener('keydown', function (ev) {
116 if (ev.target.nodeName === 'INPUT' || ev.target.nodeName === 'TEXTAREA')
117 return
118 switch(ev.keyCode) {
119
120 // scroll through tabs
121 case 72: // h
122 return tabs.selectRelative(-1)
123 case 76: // l
124 return tabs.selectRelative(1)
125
126 // scroll through messages
127 case 74: // j
128 return tabs.get(tabs.selected[0]).scroll(1)
129 case 75: // k
130 return tabs.get(tabs.selected[0]).scroll(-1)
131
132 // close a tab
133 case 88: // x
134 if (tabs.selected) {
135 var sel = tabs.selected
136 var i = sel.reduce(function (a, b) { return Math.min(a, b) })
137 tabs.remove(sel)
138 tabs.select(Math.max(i-1, 0))
139 }
140 return
141
142 // activate the search field
143 case 191: // /
144 if (ev.shiftKey)
145 search.activate('?', ev)
146 else
147 search.activate('/', ev)
148 return
149
150 // navigate to a feed
151 case 50: // 2
152 if (ev.shiftKey)
153 search.activate('@', ev)
154 return
155
156 // navigate to a channel
157 case 51: // 3
158 if (ev.shiftKey)
159 search.activate('#', ev)
160 return
161
162 // navigate to a message
163 case 53: // 5
164 if (ev.shiftKey)
165 search.activate('%', ev)
166 return
167 }
168 })
169
170 // errors tab
171 var errorsContent = h('div.column.scroller__content')
172 var errors = h('div.column.scroller', {
173 id: 'errors',
174 style: {'overflow':'auto'}
175 }, h('div.scroller__wrapper',
176 errorsContent
177 )
178 )
179
180 // remove loader error handler
181 if (window.onError) {
182 window.removeEventListener('error', window.onError)
183 delete window.onError
184 }
185
186 // put errors in a tab
187 window.addEventListener('error', function (ev) {
188 var err = ev.error || ev
189 if(!tabs.has('errors'))
190 tabs.add(errors, false)
191 var el = h('div.message',
192 h('strong', err.message),
193 h('pre', err.stack))
194 if (errorsContent.firstChild)
195 errorsContent.insertBefore(el, errorsContent.firstChild)
196 else
197 errorsContent.appendChild(el)
198 })
199
200 if (process.versions.electron) {
201 window.addEventListener('contextmenu', function (ev) {
202 ev.preventDefault()
203 var remote = require('electron').remote
204 var Menu = remote.Menu
205 var MenuItem = remote.MenuItem
206 var menu = new Menu()
207 menu.append(new MenuItem({
208 label: 'Inspect Element',
209 click: function () {
210 remote.getCurrentWindow().inspectElement(ev.x, ev.y)
211 }
212 }))
213 menu.popup(remote.getCurrentWindow())
214 })
215 }
216
217 return tabs
218 }
219
220}
221

Built with git-ssb-web