-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnavigable.js
96 lines (80 loc) · 2.54 KB
/
navigable.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
import {TargetObserver} from './TargetObserver.js';
import {U1TargetObserver, toggleParam} from './U1TargetObserver.js';
// translate hash-links to "u1-navigable"-elements into "u1-target"-params
new TargetObserver({
on: (el) => {
toggleParam(el.id, true, true);
const url = new URL(location);
url.hash = '';
history.replaceState(null, '', url.href);
},
matches: '[u1-navigable]'
})
/* dialog element */
new U1TargetObserver({
on: el => !el.open && el.showModal(),
off: el => el.close(),
matches: 'dialog[u1-navigable]',
});
addEventListener('close',e=>{
const el = e.target;
if (!el.matches('dialog[u1-navigable]')) return;
toggleParam(el.id, false);
},true);
/* details */
new U1TargetObserver({
on: el => el.open = true,
off: el => el.open = false,
matches: 'details[u1-navigable]',
});
addEventListener('toggle',e=>{
const el = e.target;
if (!el.matches('details[u1-navigable][id]')) return;
if (el.open) toggleParam(el.id, true);
else toggleParam(el.id, false);
},true);
/* checkbox and radio */
new U1TargetObserver({
on: el => el.checked = true,
off: el => el.checked = false,
matches: 'input:is([type=checkbox],[type=radio])[u1-navigable]',
});
addEventListener('change',e=>{
const el = e.target;
if (!el.matches('input:is([type=checkbox],[type=radio])[u1-navigable][id]')) return;
if (el.type === 'radio') {
const elements = el.form ? el.form.elements[el.name] : document.getElementsByName(el.name);
elements.forEach(e => toggleParam(e.id, false)); // toggleParam(e.id, false, TRUE) does not work as expected, why?
}
if (el.checked) toggleParam(el.id, true);
else toggleParam(el.id, false);
});
/* popover */
new U1TargetObserver({
on: el => el.showPopover(),
off: el => el.hidePopover(),
matches: '[popover][u1-navigable]',
});
addEventListener('toggle', e => {
const el = e.target;
if (!el.matches('[popover][u1-navigable][id]')) return;
const newState = e.newState;
toggleParam(el.id, newState === 'open');
}, true);
/* *
// todo: unified close button
addEventListener('click', e => {
const el = e.target;
if (!el.matches('[u1-navigable-close]')) return;
const id = el.getAttribute('u1-navigable-close') || el.closest('[u1-navigable]').id;
toggleParam(id, false);
}, true);
/* */
// beta
// u1 unified api
addEventListener('u1-activate', e => {
if (!e.target.hasAttribute('u1-navigable')) return;
if (!e.target.hasAttribute('id')) { console.warn('element with a u1-navigable attribute must have an id'); return; }
//e.preventDefault(); // needed?
location.href = '#' + e.target.id;
});