UNPKG

bootstrap-vue

Version:

BootstrapVue provides one of the most comprehensive implementations of Bootstrap 4 components and grid system for Vue.js and with extensive and automated WAI-ARIA accessibility markup.

165 lines (149 loc) 4.32 kB
import Popper from 'popper.js' import PopOver from '../../utils/popover.class' import { assign, keys } from '../../utils/object' import warn from '../../utils/warn' const inBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' // Key which we use to store tooltip object on element const BVPO = '__BV_PopOver__' // Valid event triggers const validTriggers = { 'focus': true, 'hover': true, 'click': true, 'blur': true } // Build a PopOver config based on bindings (if any) // Arguments and modifiers take precedence over pased value config object /* istanbul ignore next: not easy to test */ function parseBindings (bindings) { // We start out with a blank config let config = {} // Process bindings.value if (typeof bindings.value === 'string') { // Value is popover content (html optionally supported) config.content = bindings.value } else if (typeof bindings.value === 'function') { // Content generator function config.content = bindings.value } else if (typeof bindings.value === 'object') { // Value is config object, so merge config = assign(bindings.value) } // If Argument, assume element ID of container element if (bindings.arg) { // Element ID specified as arg. We must prepend '#' to become a CSS selector config.container = `#${bindings.arg}` } // Process modifiers keys(bindings.modifiers).forEach(mod => { if (/^html$/.test(mod)) { // Title allows HTML config.html = true } else if (/^nofade$/.test(mod)) { // no animation config.animation = false } else if (/^(auto|top(left|right)?|bottom(left|right)?|left(top|bottom)?|right(top|bottom)?)$/.test(mod)) { // placement of popover config.placement = mod } else if (/^(window|viewport)$/.test(mod)) { // bounday of popover config.boundary = mod } else if (/^d\d+$/.test(mod)) { // delay value const delay = parseInt(mod.slice(1), 10) || 0 if (delay) { config.delay = delay } } else if (/^o-?\d+$/.test(mod)) { // offset value (negative allowed) const offset = parseInt(mod.slice(1), 10) || 0 if (offset) { config.offset = offset } } }) // Special handling of event trigger modifiers Trigger is a space separated list const selectedTriggers = {} // parse current config object trigger let triggers = typeof config.trigger === 'string' ? config.trigger.trim().split(/\s+/) : [] triggers.forEach(trigger => { if (validTriggers[trigger]) { selectedTriggers[trigger] = true } }) // Parse Modifiers for triggers keys(validTriggers).forEach(trigger => { if (bindings.modifiers[trigger]) { selectedTriggers[trigger] = true } }) // Sanitize triggers config.trigger = keys(selectedTriggers).join(' ') if (config.trigger === 'blur') { // Blur by itself is useless, so convert it to focus config.trigger = 'focus' } if (!config.trigger) { // remove trigger config delete config.trigger } return config } // // Add or Update popover on our element // /* istanbul ignore next: not easy to test */ function applyBVPO (el, bindings, vnode) { if (!inBrowser) { return } if (!Popper) { // Popper is required for tooltips to work warn('v-b-popover: Popper.js is required for popovers to work') return } if (el[BVPO]) { el[BVPO].updateConfig(parseBindings(bindings)) } else { el[BVPO] = new PopOver(el, parseBindings(bindings), vnode.context.$root) } }; // // Remove popover on our element // /* istanbul ignore next */ function removeBVPO (el) { if (!inBrowser) { return } if (el[BVPO]) { el[BVPO].destroy() el[BVPO] = null delete el[BVPO] } } /* * Export our directive */ /* istanbul ignore next: not easy to test */ export default { bind (el, bindings, vnode) { applyBVPO(el, bindings, vnode) }, inserted (el, bindings, vnode) { applyBVPO(el, bindings, vnode) }, update (el, bindings, vnode) { if (bindings.value !== bindings.oldValue) { applyBVPO(el, bindings, vnode) } }, componentUpdated (el, bindings, vnode) { if (bindings.value !== bindings.oldValue) { applyBVPO(el, bindings, vnode) } }, unbind (el) { removeBVPO(el) } }