git ssb

0+

dangerousbeans / hyperstraptabs



forked from Dominic / hypertabs

Tree: 3e757a68dfb99a069819809d6d5e59e86d3bc91f

Files: 3e757a68dfb99a069819809d6d5e59e86d3bc91f / menu.js

3255 bytesRaw
1var h = require('hyperscript')
2var u = require('./util')
3var each = u.each
4var find = u.find
5
6function displayable (el) {
7 return el.style.display !== 'none'
8}
9
10function toggle_focus(el) {
11 if(el.style.display === 'none')
12 focus(el)
13 else
14 blur(el)
15}
16
17function focus(el) {
18 if(el.style.display !== 'flex') {
19 el.style.display = 'flex'
20 el.dispatchEvent(new CustomEvent('focus', {target: el}))
21 }
22}
23
24function blur (el) {
25 if(el.style.display !== 'none') {
26 el.style.display = 'none'
27 el.dispatchEvent(new CustomEvent('blur', {target: el}))
28 }
29}
30
31function moveTo(el, list, i) {
32 if(!list.children.length || i >= list.children.length)
33 list.appendChild(el)
34 else
35 list.insertBefore(el, list.children[i])
36}
37
38module.exports = function (list, onSelect) {
39 var menu = h('ul.nav.navbar-nav')
40 var header = h('div.navbar-header',
41 // Page brand
42 h('a.navbar-brand.logo', {href: "#"}, "PB"))
43 header.insertBefore(menu, null)
44 var wrap = header
45
46 var selection
47
48 function tab_button (el, onclick) {
49 var link = h('a.shrink.hypertabs__button', {href: '#', onclick: function (ev) {
50 if(ev.shiftKey) toggle_focus(el)
51 else {
52 each(list.children, function (tab) {
53 if(tab == el) focus(tab)
54 else blur(tab)
55 })
56 }
57 ev.preventDefault()
58 ev.stopPropagation()
59 }}, el.title || el.id || el.tagName)
60 var rm = h('button.hypertabs__x.close', {href: '#', type: 'button', onclick: function (ev) {
61 el.parentNode.removeChild(el)
62 menu.removeChild(wrap)
63 }}, 'x')
64
65 var wrap = h('li', link, rm)
66
67 function isSelected () {
68 if(displayable(el))
69 wrap.classList.add('active')
70 else
71 wrap.classList.remove('active')
72
73 if(el.classList.contains('hypertabs--notify')) {
74 wrap.classList.add('hypertabs--notify')
75 } else
76 wrap.classList.remove('hypertabs--notify')
77 }
78
79 new MutationObserver(function (changes) {
80 if(el.title !== link.innerText)
81 link.innerText = el.title || el.id || el.tagName
82 isSelected()
83 onSelect && onSelect()
84 }).observe(el, {attributes: true, attributeFilter: ['title', 'style', 'class']})
85
86 isSelected()
87 wrap.follows = el
88 return wrap
89 }
90
91 new MutationObserver(function (changes) {
92 //iterate over the list, and check that menu is in same order,
93 //add any which do not exist, remove any which no longer exist.
94
95 //check if a tab represented by a menu item has been removed.
96 each(menu.children, function (btn) {
97 if(btn.follows.parentNode != list) menu.removeChild(btn)
98 })
99
100 //check if each thing in the list has a tab.
101 each(list.children, function (tab, i) {
102 var j
103 if(menu.children[i] && menu.children[i].follows === tab) {
104 //already set, and in correct place. do nothing
105 } else if(~(j = find(menu, function (btn) { return btn.follows === tab }))) {
106 moveTo(menu[j], list, i)
107 } else {
108 menu.appendChild(tab_button(tab)) }
109 })
110
111 //check if a tab represented by a menu item has been removed.
112 each(menu.children, function (btn) {
113 if(btn.follows.parentNode != list) menu.removeChild(btn)
114 })
115
116 }).observe(list, {childList: true})
117 return wrap
118}
119

Built with git-ssb-web