1
-
import { setAttr, removeAttr } from '../../utils/dom'
2
-
import { bindTargets, unbindTargets } from '../../utils/target'
3
-
4
-
// Target listen types
5
-
const listenTypes = { click: true }
1
+
import {
2
+
eventOn,
3
+
eventOff,
4
+
getAttr,
5
+
hasAttr,
6
+
isDisabled,
7
+
matches,
8
+
select,
9
+
setAttr
10
+
} from '../../utils/dom'
11
+
import { isString } from '../../utils/inspect'
12
+
import { keys } from '../../utils/object'
6
13
7
14
// Emitted show event for modal
8
15
const EVENT_SHOW = 'bv::show::modal'
9
16
10
-
const setRole = (el, binding, vnode) => {
11
-
if (el.tagName !== 'BUTTON') {
12
-
setAttr(el, 'role', 'button')
17
+
// Prop name we use to store info on root element
18
+
const HANDLER = '__bv_modal_directive__'
19
+
20
+
const EVENT_OPTS = { passive: true }
21
+
22
+
const getTarget = ({ modifiers = {}, arg, value }) => {
23
+
// Try value, then arg, otherwise pick last modifier
24
+
return isString(value) ? value : isString(arg) ? arg : keys(modifiers).reverse()[0]
25
+
}
26
+
27
+
const getTriggerElement = el => {
28
+
// If root element is a dropdown item or nav item, we
29
+
// need to target the inner link or button instead
30
+
return el && matches(el, '.dropdown-menu > li, li.nav-item') ? select('a, button', el) || el : el
31
+
}
32
+
33
+
const setRole = trigger => {
34
+
// Only set a role if the trigger element doesn't have one
35
+
if (trigger && trigger.tagName !== 'BUTTON' && !hasAttr(trigger, 'role')) {
36
+
setAttr(trigger, 'role', 'button')
13
37
}
14
38
}
15
39
40
+
const bind = (el, binding, vnode) => {
41
+
const target = getTarget(binding)
42
+
const trigger = getTriggerElement(el)
43
+
if (target && trigger) {
44
+
const handler = evt => {
45
+
// `currentTarget` is the element with the listener on it
46
+
const currentTarget = evt.currentTarget
47
+
if (!isDisabled(currentTarget)) {
48
+
const type = evt.type
49
+
// Open modal only if trigger is not disabled
50
+
if (type === 'click' || (type === 'keydown' && evt.keyCode === 32)) {
51
+
vnode.context.$root.$emit(EVENT_SHOW, target, currentTarget)
52
+
}
53
+
}
54
+
}
55
+
el[HANDLER] = handler
56
+
// If element is not a button, we add `role="button"` for accessibility
57
+
setRole(trigger)
58
+
// Listen for click events
59
+
eventOn(trigger, 'click', handler, EVENT_OPTS)
60
+
if (trigger.tagName !== 'BUTTON' && getAttr(trigger, 'role') === 'button') {
61
+
// If trigger isn't a button but has role button,
62
+
// we also listen for `keydown.space`
63
+
eventOn(trigger, 'keydown', handler, EVENT_OPTS)
64
+
}
65
+
}
66
+
}
67
+
68
+
const unbind = el => {
69
+
const trigger = getTriggerElement(el)
70
+
const handler = el ? el[HANDLER] : null
71
+
if (trigger && handler) {
72
+
eventOff(trigger, 'click', handler, EVENT_OPTS)
73
+
eventOff(trigger, 'keydown', handler, EVENT_OPTS)
74
+
}
75
+
delete el[HANDLER]
76
+
}
77
+
78
+
const componentUpdated = (el, binding, vnode) => {
79
+
// We bind and rebind just in case target changes
80
+
unbind(el, binding, vnode)
81
+
bind(el, binding, vnode)
82
+
}
83
+
84
+
const updated = () => {}
85
+
16
86
/*
17
87
* Export our directive
18
88
*/
19
89
export const VBModal = {
20
-
// eslint-disable-next-line no-shadow-restricted-names
21
-
bind(el, binding, vnode) {
22
-
bindTargets(vnode, binding, listenTypes, ({ targets, vnode }) => {
23
-
targets.forEach(target => {
24
-
vnode.context.$root.$emit(EVENT_SHOW, target, vnode.elm)
25
-
})
26
-
})
27
-
// If element is not a button, we add `role="button"` for accessibility
28
-
setRole(el, binding, vnode)
29
-
},
30
-
updated: setRole,
31
-
componentUpdated: setRole,
32
-
unbind(el, binding, vnode) {
33
-
unbindTargets(vnode, binding, listenTypes)
34
-
// If element is not a button, we add `role="button"` for accessibility
35
-
if (el.tagName !== 'BUTTON') {
36
-
removeAttr(el, 'role', 'button')
37
-
}
38
-
}
90
+
inserted: componentUpdated,
91
+
updated,
92
+
componentUpdated,
93
+
unbind
39
94
}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4