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.75 kB
JavaScript
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
import Popper from 'popper.js';
import ToolTip from '../../utils/tooltip.class';
import { assign, keys } from '../../utils/object';
import warn from '../../utils/warn';
var inBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
// Key which we use to store tooltip object on element
var BVTT = '__BV_ToolTip__';
// Valid event triggers
var validTriggers = {
'focus': true,
'hover': true,
'click': true,
'blur': true
// Build a ToolTip config based on bindings (if any)
// Arguments and modifiers take precedence over passed value config object
/* istanbul ignore next: not easy to test */
};function parseBindings(bindings) {
// We start out with a blank config
var config = {};
// Process bindings.value
if (typeof bindings.value === 'string') {
// Value is tooltip content (html optionally supported)
config.title = bindings.value;
} else if (typeof bindings.value === 'function') {
// Title generator function
config.title = 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(function (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 tooltip
config.placement = mod;
} else if (/^(window|viewport)$/.test(mod)) {
// bounday of tooltip
config.boundary = mod;
} else if (/^d\d+$/.test(mod)) {
// delay value
var delay = parseInt(mod.slice(1), 10) || 0;
if (delay) {
config.delay = delay;
}
} else if (/^o-?\d+$/.test(mod)) {
// offset value. Negative allowed
var offset = parseInt(mod.slice(1), 10) || 0;
if (offset) {
config.offset = offset;
}
}
});
// Special handling of event trigger modifiers Trigger is a space separated list
var selectedTriggers = {};
// parse current config object trigger
var triggers = typeof config.trigger === 'string' ? config.trigger.trim().split(/\s+/) : [];
triggers.forEach(function (trigger) {
if (validTriggers[trigger]) {
selectedTriggers[trigger] = true;
}
});
// Parse Modifiers for triggers
keys(validTriggers).forEach(function (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 tooltip on our element
//
/* istanbul ignore next: not easy to test */
function applyBVTT(el, bindings, vnode) {
if (!inBrowser) {
return;
}
if (!Popper) {
// Popper is required for tooltips to work
warn('v-b-tooltip: Popper.js is required for tooltips to work');
return;
}
if (el[BVTT]) {
el[BVTT].updateConfig(parseBindings(bindings));
} else {
el[BVTT] = new ToolTip(el, parseBindings(bindings), vnode.context.$root);
}
}
//
// Remove tooltip on our element
//
/* istanbul ignore next: not easy to test */
function removeBVTT(el) {
if (!inBrowser) {
return;
}
if (el[BVTT]) {
el[BVTT].destroy();
el[BVTT] = null;
delete el[BVTT];
}
}
/*
* Export our directive
*/
/* istanbul ignore next: not easy to test */
export default {
bind: function bind(el, bindings, vnode) {
applyBVTT(el, bindings, vnode);
},
inserted: function inserted(el, bindings, vnode) {
applyBVTT(el, bindings, vnode);
},
update: function update(el, bindings, vnode) {
if (bindings.value !== bindings.oldValue) {
applyBVTT(el, bindings, vnode);
}
},
componentUpdated: function componentUpdated(el, bindings, vnode) {
if (bindings.value !== bindings.oldValue) {
applyBVTT(el, bindings, vnode);
}
},
unbind: function unbind(el) {
removeBVTT(el);
}
};