git ssb

16+

Dominic / patchbay



Tree: abc981ed003091aaeb68aab6d203e6356ea262a8

Files: abc981ed003091aaeb68aab6d203e6356ea262a8 / modules_core / tabs.js

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

Built with git-ssb-web