UNPKG

bootstrap-vue

Version:

With more than 85 components, over 45 available plugins, several directives, and 1000+ icons, BootstrapVue provides one of the most comprehensive implementations of the Bootstrap v4 component and grid system available for Vue.js v2.6, complete with extens

131 lines (109 loc) 3.67 kB
import ScrollSpy from './scrollspy.class'; import { isBrowser } from '../../utils/env'; import { isNumber, isObject, isString } from '../../utils/inspect'; import { mathRound } from '../../utils/math'; import { toInteger } from '../../utils/number'; import { keys } from '../../utils/object'; // Key we use to store our instance var BV_SCROLLSPY = '__BV_ScrollSpy__'; // Pre-compiled regular expressions var onlyDigitsRE = /^\d+$/; var offsetRE = /^(auto|position|offset)$/; // Build a ScrollSpy config based on bindings (if any) // Arguments and modifiers take precedence over passed value config object /* istanbul ignore next: not easy to test */ var parseBindings = function parseBindings(bindings) /* istanbul ignore next: not easy to test */ { var config = {}; // If argument, assume element ID if (bindings.arg) { // Element ID specified as arg // We must prepend '#' to become a CSS selector config.element = "#".concat(bindings.arg); } // Process modifiers keys(bindings.modifiers).forEach(function (mod) { if (onlyDigitsRE.test(mod)) { // Offset value config.offset = toInteger(mod, 0); } else if (offsetRE.test(mod)) { // Offset method config.method = mod; } }); // Process value if (isString(bindings.value)) { // Value is a CSS ID or selector config.element = bindings.value; } else if (isNumber(bindings.value)) { // Value is offset config.offset = mathRound(bindings.value); } else if (isObject(bindings.value)) { // Value is config object // Filter the object based on our supported config options keys(bindings.value).filter(function (k) { return !!ScrollSpy.DefaultType[k]; }).forEach(function (k) { config[k] = bindings.value[k]; }); } return config; }; // Add or update ScrollSpy on our element var applyScrollspy = function applyScrollspy(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { if (!isBrowser) { /* istanbul ignore next */ return; } var config = parseBindings(bindings); if (el[BV_SCROLLSPY]) { el[BV_SCROLLSPY].updateConfig(config, vnode.context.$root); } else { el[BV_SCROLLSPY] = new ScrollSpy(el, config, vnode.context.$root); } }; // Remove ScrollSpy on our element /* istanbul ignore next: not easy to test */ var removeScrollspy = function removeScrollspy(el) /* istanbul ignore next: not easy to test */ { if (el[BV_SCROLLSPY]) { el[BV_SCROLLSPY].dispose(); el[BV_SCROLLSPY] = null; delete el[BV_SCROLLSPY]; } }; /* * Export our directive */ export var VBScrollspy = { /* istanbul ignore next: not easy to test */ bind: function bind(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { applyScrollspy(el, bindings, vnode); }, /* istanbul ignore next: not easy to test */ inserted: function inserted(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { applyScrollspy(el, bindings, vnode); }, /* istanbul ignore next: not easy to test */ update: function update(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { if (bindings.value !== bindings.oldValue) { applyScrollspy(el, bindings, vnode); } }, /* istanbul ignore next: not easy to test */ componentUpdated: function componentUpdated(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { if (bindings.value !== bindings.oldValue) { applyScrollspy(el, bindings, vnode); } }, /* istanbul ignore next: not easy to test */ unbind: function unbind(el) /* istanbul ignore next: not easy to test */ { removeScrollspy(el); } };