-
Notifications
You must be signed in to change notification settings - Fork 101
/
Copy pathtabs.js
141 lines (118 loc) · 3.34 KB
/
tabs.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
var h = require('hyperscript')
var u = require('./lib/util')
each = u.each,
find = u.find,
isVisible = u.isVisible,
setVisible = u.setVisible,
setInvisible = u.setInvisible
function toggle_focus(page) {
isVisible(page)
? blur(page)
: focus(page)
}
function focus(page) {
if (isVisible(page)) return
setVisible(page)
var el = page.firstChild
el.dispatchEvent(new CustomEvent('focus', {target: el}))
}
function blur (page) {
if (!isVisible(page)) return
setInvisible(page)
var el = page.firstChild
el.dispatchEvent(new CustomEvent('blur', {target: el}))
}
function moveTo(page, content, i) {
if(!content.children.length || i >= content.children.length)
content.appendChild(page)
else
content.insertBefore(page, content.children[i])
}
module.exports = function (content, onSelect, onClose) {
var tabs = h('section.tabs')
var selection
function build_tab (page) {
function close () {
page.parentNode.removeChild(page)
tabs.removeChild(tab)
onClose && onClose(page.firstChild)
}
var link = h('a.link', {
href: '#',
onclick: function (ev) {
ev.preventDefault()
ev.stopPropagation()
if(ev.shiftKey) toggle_focus(page)
else {
each(content.children, function (_page) {
if(_page == page) focus(_page)
else blur(_page)
})
}
},
onauxclick: function (ev) {
if(ev.which && ev.which === 2) {
ev.preventDefault()
ev.stopPropagation()
close()
}
}},
getTitle(page)
)
var rm = h('a.close', {
href: '#',
onclick: function (ev) {
ev.preventDefault()
ev.stopPropagation()
close()
}},
'x'
)
var tab = h('div.tab', [
link, rm
])
function updateTabClasses () {
if(isVisible(page))
tab.classList.add('-selected')
else
tab.classList.remove('-selected')
if(page.classList.contains('-notify'))
tab.classList.add('-notify')
else
tab.classList.remove('-notify')
}
function getTitle(page) {
var el = page.firstChild
return el.title || el.id || el.tagName
}
new MutationObserver(function (changes) {
if(page.title !== link.innerText)
link.innerText = getTitle(page)
updateTabClasses()
onSelect && onSelect()
}).observe(page, {attributes: true, attributeFilter: ['title', 'style', 'class']})
updateTabClasses()
tab.page = page
return tab
}
new MutationObserver(function (changes) {
//iterate over the content, and check that tabs is in same order,
//add any which do not exist, remove any which no longer exist.
//check if a page represented by a tab has been removed.
each(tabs.children, function (tab) {
if(tab.page.parentNode != content) tabs.removeChild(tab)
})
//check if each page in the content has a tab.
each(content.children, function (page, i) {
var j
if(tabs.children[i] && tabs.children[i].page === page) {
//already set, and in correct place. do nothing
} else if(~(j = find(tabs, function (tab) { return tab.page === page }))) {
moveTo(tabs[j], content, i)
} else {
tabs.appendChild(build_tab(page))
}
})
}).observe(content, {childList: true})
return tabs
}