You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
3.3 KiB
121 lines
3.3 KiB
4 years ago
|
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) {
|
||
|
applyScrollspy(el, bindings, vnode);
|
||
|
},
|
||
|
|
||
|
/* istanbul ignore next: not easy to test */
|
||
|
inserted: function inserted(el, bindings, vnode) {
|
||
|
applyScrollspy(el, bindings, vnode);
|
||
|
},
|
||
|
|
||
|
/* istanbul ignore next: not easy to test */
|
||
|
update: function update(el, bindings, vnode) {
|
||
|
if (bindings.value !== bindings.oldValue) {
|
||
|
applyScrollspy(el, bindings, vnode);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/* istanbul ignore next: not easy to test */
|
||
|
componentUpdated: function componentUpdated(el, bindings, vnode) {
|
||
|
if (bindings.value !== bindings.oldValue) {
|
||
|
applyScrollspy(el, bindings, vnode);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/* istanbul ignore next: not easy to test */
|
||
|
unbind: function unbind(el) {
|
||
|
removeScrollspy(el);
|
||
|
}
|
||
|
};
|