git ssb

16+

Dominic / patchbay



Tree: f5019994e9135c7fd3dd5614b1006254d170cf63

Files: f5019994e9135c7fd3dd5614b1006254d170cf63 / modules_core / tabs.js

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

Built with git-ssb-web