git ssb

16+

Dominic / patchbay



Tree: 6ae6f1ce78d440dea5e42c9ab6d0112732b161f6

Files: 6ae6f1ce78d440dea5e42c9ab6d0112732b161f6 / modules_core / tabs.js

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

Built with git-ssb-web