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.
 
 
 
 
 
 
zhishifufei_php/public/static/plug/vuescroll/vuescroll-native.js

2558 lines
72 KiB

/*
* Vuescroll v4.16.1
* (c) 2018-2020 Yi(Yves) Wang
* Released under the MIT License
* Github: https://github.com/YvesCoding/vuescroll
* Website: http://vuescrolljs.yvescoding.org/
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('vue')) :
typeof define === 'function' && define.amd ? define(['vue'], factory) :
(global.vuescroll = factory(global.Vue));
}(this, (function (Vue) { 'use strict';
Vue = Vue && Vue.hasOwnProperty('default') ? Vue['default'] : Vue;
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;
};
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var defineProperty = function (obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
};
var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
var toConsumableArray = function (arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
} else {
return Array.from(arr);
}
};
function isIE() {
/* istanbul ignore if */
if (isServer()) return false;
var agent = navigator.userAgent.toLowerCase();
return agent.indexOf('msie') !== -1 || agent.indexOf('trident') !== -1 || agent.indexOf(' edge/') !== -1;
}
var isIos = function isIos() {
/* istanbul ignore if */
if (isServer()) return false;
var u = navigator.userAgent;
return !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
};
/* istanbul ignore next */
var isServer = function isServer() {
return Vue.prototype.$isServer;
};
var touchManager = function () {
function touchManager() {
classCallCheck(this, touchManager);
}
createClass(touchManager, [{
key: 'getEventObject',
value: function getEventObject(originEvent) {
return this.touchObject ? this.isTouch ? originEvent.touches : [originEvent] : null;
}
}, {
key: 'getTouchObject',
value: function getTouchObject() /* istanbul ignore next */{
if (isServer()) return null;
this.isTouch = false;
var agent = navigator.userAgent,
platform = navigator.platform,
touchObject = {};
touchObject.touch = !!('ontouchstart' in window && !window.opera || 'msmaxtouchpoints' in window.navigator || 'maxtouchpoints' in window.navigator || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0);
touchObject.nonDeskTouch = touchObject.touch && !/win32/i.test(platform) || touchObject.touch && /win32/i.test(platform) && /mobile/i.test(agent);
touchObject.eventType = 'onmousedown' in window && !touchObject.nonDeskTouch ? 'mouse' : 'ontouchstart' in window ? 'touch' : 'msmaxtouchpoints' in window.navigator || navigator.msMaxTouchPoints > 0 ? 'mstouchpoints' : 'maxtouchpoints' in window.navigator || navigator.maxTouchPoints > 0 ? 'touchpoints' : 'mouse';
switch (touchObject.eventType) {
case 'mouse':
touchObject.touchstart = 'mousedown';
touchObject.touchend = 'mouseup';
touchObject.touchmove = 'mousemove';
touchObject.touchenter = 'mouseenter';
touchObject.touchmove = 'mousemove';
touchObject.touchleave = 'mouseleave';
break;
case 'touch':
touchObject.touchstart = 'touchstart';
touchObject.touchend = 'touchend';
touchObject.touchmove = 'touchmove';
touchObject.touchcancel = 'touchcancel';
touchObject.touchenter = 'touchstart';
touchObject.touchmove = 'touchmove';
touchObject.touchleave = 'touchend';
this.isTouch = true;
break;
case 'mstouchpoints':
touchObject.touchstart = 'MSPointerDown';
touchObject.touchend = 'MSPointerUp';
touchObject.touchmove = 'MSPointerMove';
touchObject.touchcancel = 'MSPointerCancel';
touchObject.touchenter = 'MSPointerDown';
touchObject.touchmove = 'MSPointerMove';
touchObject.touchleave = 'MSPointerUp';
break;
case 'touchpoints':
touchObject.touchstart = 'pointerdown';
touchObject.touchend = 'pointerup';
touchObject.touchmove = 'pointermove';
touchObject.touchcancel = 'pointercancel';
touchObject.touchenter = 'pointerdown';
touchObject.touchmove = 'pointermove';
touchObject.touchleave = 'pointerup';
break;
}
return this.touchObject = touchObject;
}
}]);
return touchManager;
}();
function deepCopy(from, to, shallow) {
if (shallow && isUndef(to)) {
return from;
}
if (isArray(from)) {
to = [];
from.forEach(function (item, index) {
to[index] = deepCopy(item, to[index]);
});
} else if (from) {
if (!isPlainObj(from)) {
return from;
}
to = {};
for (var key in from) {
to[key] = _typeof(from[key]) === 'object' ? deepCopy(from[key], to[key]) : from[key];
}
}
return to;
}
function mergeObject(from, to, force, shallow) {
if (shallow && isUndef(to)) {
return from;
}
to = to || {};
if (isArray(from)) {
if (!isArray(to) && force) {
to = [];
}
if (isArray(to)) {
from.forEach(function (item, index) {
to[index] = mergeObject(item, to[index], force, shallow);
});
}
} else if (from) {
if (!isPlainObj(from)) {
if (force) {
to = from;
}
} else {
for (var key in from) {
if (_typeof(from[key]) === 'object') {
if (isUndef(to[key])) {
to[key] = deepCopy(from[key], to[key], shallow);
} else {
mergeObject(from[key], to[key], force, shallow);
}
} else {
if (isUndef(to[key]) || force) to[key] = from[key];
}
}
}
}
return to;
}
function defineReactive(target, key, source, souceKey) {
/* istanbul ignore if */
if (!source[key] && typeof source !== 'function') {
return;
}
souceKey = souceKey || key;
Object.defineProperty(target, key, {
get: function get$$1() {
return source[souceKey];
},
configurable: true
});
}
var scrollBarWidth = void 0;
function getGutter() {
/* istanbul ignore next */
if (isServer()) return 0;
if (scrollBarWidth !== undefined) return scrollBarWidth;
var outer = document.createElement('div');
outer.style.visibility = 'hidden';
outer.style.width = '100px';
outer.style.position = 'absolute';
outer.style.top = '-9999px';
document.body.appendChild(outer);
var widthNoScroll = outer.offsetWidth;
outer.style.overflow = 'scroll';
var inner = document.createElement('div');
inner.style.width = '100%';
outer.appendChild(inner);
var widthWithScroll = inner.offsetWidth;
outer.parentNode.removeChild(outer);
scrollBarWidth = widthNoScroll - widthWithScroll;
return scrollBarWidth;
}
function eventCenter(dom, eventName, hander) {
var capture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var type = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 'on';
type == 'on' ? dom.addEventListener(eventName, hander, capture) : dom.removeEventListener(eventName, hander, capture);
}
var warn = function warn(msg) {
console.warn('[vuescroll] ' + msg);
};
function isChildInParent(child, parent) {
var flag = false;
if (!child || !parent) {
return flag;
}
while (child.parentNode !== parent && child.parentNode.nodeType !== 9 && !child.parentNode._isVuescroll) {
child = child.parentNode;
}
if (child.parentNode == parent) {
flag = true;
}
return flag;
}
function getPrefix(global) {
var docStyle = document.documentElement.style;
var engine;
/* istanbul ignore if */
if (global.opera && Object.prototype.toString.call(opera) === '[object Opera]') {
engine = 'presto';
} /* istanbul ignore next */else if ('MozAppearance' in docStyle) {
engine = 'gecko';
} else if ('WebkitAppearance' in docStyle) {
engine = 'webkit';
} /* istanbul ignore next */else if (typeof navigator.cpuClass === 'string') {
engine = 'trident';
}
var vendorPrefix = {
trident: 'ms',
gecko: 'moz',
webkit: 'webkit',
presto: 'O'
}[engine];
return vendorPrefix;
}
function getComplitableStyle(property, value) {
/* istanbul ignore if */
if (isServer()) return false;
var compatibleValue = '-' + getPrefix(window) + '-' + value;
var testElm = document.createElement('div');
testElm.style[property] = compatibleValue;
if (testElm.style[property] == compatibleValue) {
return compatibleValue;
}
/* istanbul ignore next */
return false;
}
/**
* Insert children into user-passed slot at vnode level
*/
function insertChildrenIntoSlot(h) {
var parentVnode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var childVNode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
var data = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var swapChildren = arguments[4];
/* istanbul ignore if */
if (parentVnode && parentVnode.length > 1) {
return swapChildren ? [].concat(toConsumableArray(childVNode), toConsumableArray(parentVnode)) : [].concat(toConsumableArray(parentVnode), toConsumableArray(childVNode));
}
parentVnode = parentVnode[0];
var _getVnodeInfo = getVnodeInfo(parentVnode),
ch = _getVnodeInfo.ch,
tag = _getVnodeInfo.tag,
isComponent = _getVnodeInfo.isComponent;
if (isComponent) {
parentVnode.data = mergeObject({ attrs: parentVnode.componentOptions.propsData }, parentVnode.data, false, // force: false
true // shallow: true
);
}
ch = swapChildren ? [].concat(toConsumableArray(childVNode), toConsumableArray(ch)) : [].concat(toConsumableArray(ch), toConsumableArray(childVNode));
delete parentVnode.data.slot;
return h(tag, mergeObject(data, parentVnode.data, false, true), ch);
}
/**
* Get the info of a vnode,
* vnode must be parentVnode
*/
function getVnodeInfo(vnode) {
if (!vnode || vnode.length > 1) return {};
vnode = vnode[0] ? vnode[0] : vnode;
var isComponent = !!vnode.componentOptions;
var ch = void 0;
var tag = void 0;
if (isComponent) {
ch = vnode.componentOptions.children || [];
tag = vnode.componentOptions.tag;
} else {
ch = vnode.children || [];
tag = vnode.tag;
}
return {
isComponent: isComponent,
ch: ch,
tag: tag
};
}
/**
* Get the vuescroll instance instead of
* user pass component like slot.
*/
function getRealParent(ctx) {
var parent = ctx.$parent;
if (!parent._isVuescrollRoot && parent) {
parent = parent.$parent;
}
return parent;
}
var isArray = function isArray(_) {
return Array.isArray(_);
};
var isPlainObj = function isPlainObj(_) {
return Object.prototype.toString.call(_) == '[object Object]';
};
var isUndef = function isUndef(_) {
return typeof _ === 'undefined';
};
function getNumericValue(distance, size) {
var number = void 0;
if (!(number = /(-?\d+(?:\.\d+?)?)%$/.exec(distance))) {
number = distance - 0;
} else {
number = number[1] - 0;
number = size * number / 100;
}
return number;
}
function createStyle(styleId, cssText) {
/* istanbul ignore if */
if (isServer() || document.getElementById(styleId)) {
return;
}
var head = document.head || doc.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.id = styleId;
style.type = 'text/css';
/* istanbul ignore if */
if (style.styleSheet) {
style.styleSheet.cssText = cssText;
} else {
style.appendChild(document.createTextNode(cssText));
}
head.appendChild(style);
}
// Hide the ios native scrollbar.
function createHideBarStyle() {
/* istanbul ignore next */
{
var cssText = '.__hidebar::-webkit-scrollbar {\n width: 0;\n height: 0;\n }';
createStyle('vuescroll-hide-ios-bar', cssText);
}
}
// create slide mode style
var api = {
mounted: function mounted() {
vsInstances[this._uid] = this;
},
beforeDestroy: function beforeDestroy() {
delete vsInstances[this._uid];
},
methods: {
// public api
scrollTo: function scrollTo(_ref, speed, easing) {
var x = _ref.x,
y = _ref.y;
// istanbul ignore if
if (speed === true || typeof speed == 'undefined') {
speed = this.mergedOptions.scrollPanel.speed;
}
this.internalScrollTo(x, y, speed, easing);
},
scrollBy: function scrollBy(_ref2, speed, easing) {
var _ref2$dx = _ref2.dx,
dx = _ref2$dx === undefined ? 0 : _ref2$dx,
_ref2$dy = _ref2.dy,
dy = _ref2$dy === undefined ? 0 : _ref2$dy;
var _getPosition = this.getPosition(),
_getPosition$scrollLe = _getPosition.scrollLeft,
scrollLeft = _getPosition$scrollLe === undefined ? 0 : _getPosition$scrollLe,
_getPosition$scrollTo = _getPosition.scrollTop,
scrollTop = _getPosition$scrollTo === undefined ? 0 : _getPosition$scrollTo;
if (dx) {
scrollLeft += getNumericValue(dx, this.scrollPanelElm.scrollWidth - this.$el.clientWidth);
}
if (dy) {
scrollTop += getNumericValue(dy, this.scrollPanelElm.scrollHeight - this.$el.clientHeight);
}
this.internalScrollTo(scrollLeft, scrollTop, speed, easing);
},
scrollIntoView: function scrollIntoView(elm) {
var animate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var parentElm = this.$el;
if (typeof elm === 'string') {
elm = parentElm.querySelector(elm);
}
if (!isChildInParent(elm, parentElm)) {
warn('The element or selector you passed is not the element of Vuescroll, please pass the element that is in Vuescroll to scrollIntoView API. ');
return;
}
// parent elm left, top
var _$el$getBoundingClien = this.$el.getBoundingClientRect(),
left = _$el$getBoundingClien.left,
top = _$el$getBoundingClien.top;
// child elm left, top
var _elm$getBoundingClien = elm.getBoundingClientRect(),
childLeft = _elm$getBoundingClien.left,
childTop = _elm$getBoundingClien.top;
var diffX = left - childLeft;
var diffY = top - childTop;
this.scrollBy({
dx: -diffX,
dy: -diffY
}, animate);
},
refresh: function refresh() {
this.refreshInternalStatus();
// refresh again to keep status is correct
this.$nextTick(this.refreshInternalStatus);
}
}
};
/** Public Api */
/**
* Refresh all
*/
var vsInstances = {};
function refreshAll() {
for (var vs in vsInstances) {
vsInstances[vs].refresh();
}
}
var baseConfig = {
// vuescroll
vuescroll: {
// vuescroll's size(height/width) should be a percent(100%)
// or be a number that is equal to its parentNode's width or
// height ?
sizeStrategy: 'percent',
/** Whether to detect dom resize or not */
detectResize: true
},
scrollPanel: {
// when component mounted.. it will automatically scrolls.
initialScrollY: false,
initialScrollX: false,
// feat: #11
scrollingX: true,
scrollingY: true,
speed: 300,
easing: undefined,
// Sometimes, the nativebar maybe on the left,
// See https://github.com/YvesCoding/vuescroll/issues/64
verticalNativeBarPos: 'right',
maxHeight: undefined,
maxWidth: undefined
},
//
rail: {
background: '#01a99a',
opacity: 0,
border: 'none',
/** Rail's size(Height/Width) , default -> 6px */
size: '6px',
/** Specify rail's border-radius, or the border-radius of rail and bar will be equal to the rail's size. default -> false **/
specifyBorderRadius: false,
/** Rail the distance from the two ends of the X axis and Y axis. **/
gutterOfEnds: null,
/** Rail the distance from the side of container. **/
gutterOfSide: '2px',
/** Whether to keep rail show or not, default -> false, event content height is not enough */
keepShow: false
},
bar: {
/** How long to hide bar after mouseleave, default -> 500 */
showDelay: 500,
/** Specify bar's border-radius, or the border-radius of rail and bar will be equal to the rail's size. default -> false **/
specifyBorderRadius: false,
/** Whether to show bar on scrolling, default -> true */
onlyShowBarOnScroll: true,
/** Whether to keep show or not, default -> false */
keepShow: false,
/** Bar's background , default -> #00a650 */
background: 'rgb(3, 185, 118)',
/** Bar's opacity, default -> 1 */
opacity: 1,
/** bar's size(Height/Width) , default -> 6px */
size: '6px',
minSize: 0,
disable: false
},
scrollButton: {
enable: false,
background: 'rgb(3, 185, 118)',
opacity: 1,
step: 180,
mousedownStep: 30
}
};
/**
* validate the options
* @export
* @param {any} ops
*/
function validateOps(ops) {
var renderError = false;
var scrollPanel = ops.scrollPanel;
var _ops$bar = ops.bar,
vBar = _ops$bar.vBar,
hBar = _ops$bar.hBar;
var _ops$rail = ops.rail,
vRail = _ops$rail.vRail,
hRail = _ops$rail.hRail;
// validate scrollPanel
var initialScrollY = scrollPanel['initialScrollY'];
var initialScrollX = scrollPanel['initialScrollX'];
if (initialScrollY && !String(initialScrollY).match(/^\d+(\.\d+)?(%)?$/)) {
warn('The prop `initialScrollY` or `initialScrollX` should be a percent number like `10%` or an exact number that greater than or equal to 0 like `100`.');
}
if (initialScrollX && !String(initialScrollX).match(/^\d+(\.\d+)?(%)?$/)) {
warn('The prop `initialScrollY` or `initialScrollX` should be a percent number like `10%` or an exact number that greater than or equal to 0 like `100`.');
}
// validate deprecated vBar/hBar vRail/hRail
if (vBar || hBar || vRail || hRail) {
warn('The options: vRail, hRail, vBar, hBar have been deprecated since v4.7.0,' + 'please use corresponing rail/bar instead!');
}
if (_extraValidate) {
_extraValidate = [].concat(_extraValidate);
_extraValidate.forEach(function (hasError) {
if (hasError(ops)) {
renderError = true;
}
});
}
return renderError;
}
var _extraValidate = null;
var extendOpts = function extendOpts(extraOpts, extraValidate) {
extraOpts = [].concat(extraOpts);
extraOpts.forEach(function (opts) {
mergeObject(opts, baseConfig);
});
_extraValidate = extraValidate;
};
// all modes
// do nothing
// some small changes.
var smallChangeArray = ['mergedOptions.vuescroll.pullRefresh.tips', 'mergedOptions.vuescroll.pushLoad.tips', 'mergedOptions.vuescroll.scroller.disable', 'mergedOptions.rail', 'mergedOptions.bar'];
// refresh/load dom ref/key...
var scrollMap = {
vertical: {
size: 'height',
opsSize: 'width',
posName: 'top',
opposName: 'bottom',
sidePosName: 'right',
page: 'pageY',
scroll: 'scrollTop',
scrollSize: 'scrollHeight',
offset: 'offsetHeight',
client: 'clientY',
axis: 'Y',
scrollButton: {
start: 'top',
end: 'bottom'
}
},
horizontal: {
size: 'width',
opsSize: 'height',
posName: 'left',
opposName: 'right',
sidePosName: 'bottom',
page: 'pageX',
scroll: 'scrollLeft',
scrollSize: 'scrollWidth',
offset: 'offsetWidth',
client: 'clientX',
axis: 'X',
scrollButton: {
start: 'left',
end: 'right'
}
}
};
function requestAnimationFrame(global) {
// Check for request animation Frame support
var requestFrame = global.requestAnimationFrame || global.webkitRequestAnimationFrame || global.mozRequestAnimationFrame || global.oRequestAnimationFrame;
var isNative = !!requestFrame;
if (requestFrame && !/requestAnimationFrame\(\)\s*\{\s*\[native code\]\s*\}/i.test(requestFrame.toString())) {
isNative = false;
}
if (isNative) {
return function (callback, root) {
requestFrame(callback, root);
};
}
var TARGET_FPS = 60;
var requests = {};
var rafHandle = 1;
var intervalHandle = null;
var lastActive = +new Date();
return function (callback) {
var callbackHandle = rafHandle++;
// Store callback
requests[callbackHandle] = callback;
// Create timeout at first request
if (intervalHandle === null) {
intervalHandle = setInterval(function () {
var time = +new Date();
var currentRequests = requests;
// Reset data structure before executing callbacks
requests = {};
for (var key in currentRequests) {
if (currentRequests.hasOwnProperty(key)) {
currentRequests[key](time);
lastActive = time;
}
}
// Disable the timeout when nothing happens for a certain
// period of time
if (time - lastActive > 2500) {
clearInterval(intervalHandle);
intervalHandle = null;
}
}, 1000 / TARGET_FPS);
}
return callbackHandle;
};
}
var colorCache = {};
var rgbReg = /rgb\(/;
var extractRgbColor = /rgb\((.*)\)/;
// Transform a common color int oa `rgbA` color
function getRgbAColor(color, opacity) {
var id = color + '&' + opacity;
if (colorCache[id]) {
return colorCache[id];
}
var div = document.createElement('div');
div.style.background = color;
document.body.appendChild(div);
var computedColor = window.getComputedStyle(div).backgroundColor;
document.body.removeChild(div);
/* istanbul ignore if */
if (!rgbReg.test(computedColor)) {
return color;
}
return colorCache[id] = 'rgba(' + extractRgbColor.exec(computedColor)[1] + ', ' + opacity + ')';
}
var bar = {
name: 'bar',
props: {
ops: Object,
state: Object,
hideBar: Boolean,
otherBarHide: Boolean,
type: String
},
computed: {
bar: function bar() {
return scrollMap[this.type];
},
barSize: function barSize() {
return Math.max(this.state.size, this.ops.bar.minSize);
},
barRatio: function barRatio() {
return (1 - this.barSize) / (1 - this.state.size);
}
},
render: function render(h) {
var _style, _style2, _barStyle;
var vm = this;
/** Get rgbA format background color */
var railBackgroundColor = getRgbAColor(vm.ops.rail.background, vm.ops.rail.opacity);
if (!this.touchManager) {
this.touchManager = new touchManager();
}
/** Rail Data */
var railSize = vm.ops.rail.size;
var endPos = vm.otherBarHide ? 0 : railSize;
var touchObj = vm.touchManager.getTouchObject();
var rail = {
class: '__rail-is-' + vm.type,
style: (_style = {
position: 'absolute',
'z-index': '1',
borderRadius: vm.ops.rail.specifyBorderRadius || railSize,
background: railBackgroundColor,
border: vm.ops.rail.border
}, defineProperty(_style, vm.bar.opsSize, railSize), defineProperty(_style, vm.bar.posName, vm.ops.rail['gutterOfEnds'] || 0), defineProperty(_style, vm.bar.opposName, vm.ops.rail['gutterOfEnds'] || endPos), defineProperty(_style, vm.bar.sidePosName, vm.ops.rail['gutterOfSide']), _style)
};
if (touchObj) {
var _rail$on;
rail.on = (_rail$on = {}, defineProperty(_rail$on, touchObj.touchenter, function () {
vm.setRailHover();
}), defineProperty(_rail$on, touchObj.touchleave, function () {
vm.setRailLeave();
}), _rail$on);
}
// left space for scroll button
var buttonSize = vm.ops.scrollButton.enable ? railSize : 0;
var barWrapper = {
class: '__bar-wrap-is-' + vm.type,
style: (_style2 = {
position: 'absolute',
borderRadius: vm.ops.rail.specifyBorderRadius || railSize
}, defineProperty(_style2, vm.bar.posName, buttonSize), defineProperty(_style2, vm.bar.opposName, buttonSize), _style2),
on: {}
};
var scrollDistance = vm.state.posValue * vm.state.size;
var pos = scrollDistance * vm.barRatio / vm.barSize;
var opacity = vm.state.opacity;
var parent = getRealParent(this);
// set class hook
parent.setClassHook(this.type == 'vertical' ? 'vBarVisible' : 'hBarVisible', !!opacity);
/** Scrollbar style */
var barStyle = (_barStyle = {
cursor: 'pointer',
position: 'absolute',
margin: 'auto',
transition: 'opacity 0.5s',
'user-select': 'none',
'border-radius': 'inherit'
}, defineProperty(_barStyle, vm.bar.size, vm.barSize * 100 + '%'), defineProperty(_barStyle, 'background', vm.ops.bar.background), defineProperty(_barStyle, vm.bar.opsSize, vm.ops.bar.size), defineProperty(_barStyle, 'opacity', opacity), defineProperty(_barStyle, 'transform', 'translate' + scrollMap[vm.type].axis + '(' + pos + '%)'), _barStyle);
var bar = {
style: barStyle,
class: '__bar-is-' + vm.type,
ref: 'thumb',
on: {}
};
if (vm.type == 'vertical') {
barWrapper.style.width = '100%';
// Let bar to be on the center.
bar.style.left = 0;
bar.style.right = 0;
} else {
barWrapper.style.height = '100%';
bar.style.top = 0;
bar.style.bottom = 0;
}
/* istanbul ignore next */
{
var _touchObj = this.touchManager.getTouchObject();
bar.on[_touchObj.touchstart] = this.createBarEvent();
barWrapper.on[_touchObj.touchstart] = this.createTrackEvent();
}
return h(
'div',
rail,
[this.createScrollbarButton(h, 'start'), this.hideBar ? null : h(
'div',
barWrapper,
[h('div', bar)]
), this.createScrollbarButton(h, 'end')]
);
},
data: function data() {
return {
isBarDragging: false
};
},
methods: {
setRailHover: function setRailHover() {
var parent = getRealParent(this);
var state = parent.vuescroll.state;
if (!state.isRailHover) {
state.isRailHover = true;
parent.showBar();
}
},
setRailLeave: function setRailLeave() {
var parent = getRealParent(this);
var state = parent.vuescroll.state;
state.isRailHover = false;
parent.hideBar();
},
setBarDrag: function setBarDrag(val) /* istanbul ignore next */{
this.$emit('setBarDrag', this.isBarDragging = val);
var parent = getRealParent(this);
// set class hook
parent.setClassHook(this.type == 'vertical' ? 'vBarDragging' : 'hBarDragging', !!val);
},
createBarEvent: function createBarEvent() {
var ctx = this;
var parent = getRealParent(ctx);
var touchObj = ctx.touchManager.getTouchObject();
function mousedown(e) /* istanbul ignore next */{
var event = ctx.touchManager.getEventObject(e);
if (!event) return;
e.stopImmediatePropagation();
e.preventDefault();
event = event[0];
document.onselectstart = function () {
return false;
};
ctx.axisStartPos = event[ctx.bar.client] - ctx.$refs['thumb'].getBoundingClientRect()[ctx.bar.posName];
// Tell parent that the mouse has been down.
ctx.setBarDrag(true);
eventCenter(document, touchObj.touchmove, mousemove);
eventCenter(document, touchObj.touchend, mouseup);
}
function mousemove(e) /* istanbul ignore next */{
if (!ctx.axisStartPos) {
return;
}
var event = ctx.touchManager.getEventObject(e);
if (!event) return;
event = event[0];
var thubmParent = ctx.$refs.thumb.parentNode;
var delta = event[ctx.bar.client] - thubmParent.getBoundingClientRect()[ctx.bar.posName];
delta = delta / ctx.barRatio;
var percent = (delta - ctx.axisStartPos) / thubmParent[ctx.bar.offset];
parent.scrollTo(defineProperty({}, ctx.bar.axis.toLowerCase(), parent.scrollPanelElm[ctx.bar.scrollSize] * percent), false);
}
function mouseup() /* istanbul ignore next */{
ctx.setBarDrag(false);
parent.hideBar();
document.onselectstart = null;
ctx.axisStartPos = 0;
eventCenter(document, touchObj.touchmove, mousemove, false, 'off');
eventCenter(document, touchObj.touchend, mouseup, false, 'off');
}
return mousedown;
},
createTrackEvent: function createTrackEvent() {
var ctx = this;
return function handleClickTrack(e) {
var parent = getRealParent(ctx);
var _ctx$bar = ctx.bar,
client = _ctx$bar.client,
offset = _ctx$bar.offset,
posName = _ctx$bar.posName,
axis = _ctx$bar.axis;
var thumb = ctx.$refs['thumb'];
e.preventDefault();
e.stopImmediatePropagation();
/* istanbul ignore if */
if (!thumb) return;
var barOffset = thumb[offset];
var event = ctx.touchManager.getEventObject(e)[0];
var percent = (event[client] - e.currentTarget.getBoundingClientRect()[posName] - barOffset / 2) / (e.currentTarget[offset] - barOffset);
parent.scrollTo(defineProperty({}, axis.toLowerCase(), percent * 100 + '%'));
};
},
// Scrollbuton relative things...
createScrollbarButton: function createScrollbarButton(h, type /* start or end */) {
var _style3;
var barContext = this;
if (!barContext.ops.scrollButton.enable) {
return null;
}
var size = barContext.ops.rail.size;
var _barContext$ops$scrol = barContext.ops.scrollButton,
opacity = _barContext$ops$scrol.opacity,
background = _barContext$ops$scrol.background;
var borderColor = getRgbAColor(background, opacity);
var wrapperProps = {
class: ['__bar-button', '__bar-button-is-' + barContext.type + '-' + type],
style: (_style3 = {}, defineProperty(_style3, barContext.bar.scrollButton[type], 0), defineProperty(_style3, 'width', size), defineProperty(_style3, 'height', size), defineProperty(_style3, 'position', 'absolute'), defineProperty(_style3, 'cursor', 'pointer'), defineProperty(_style3, 'display', 'table'), _style3),
ref: type
};
var innerProps = {
class: '__bar-button-inner',
style: {
border: 'calc(' + size + ' / 2.5) solid transparent',
width: '0',
height: '0',
margin: 'auto',
position: 'absolute',
top: '0',
bottom: '0',
right: '0',
left: '0'
},
on: {}
};
if (barContext.type == 'vertical') {
if (type == 'start') {
innerProps.style['border-bottom-color'] = borderColor;
innerProps.style['transform'] = 'translateY(-25%)';
} else {
innerProps.style['border-top-color'] = borderColor;
innerProps.style['transform'] = 'translateY(25%)';
}
} else {
if (type == 'start') {
innerProps.style['border-right-color'] = borderColor;
innerProps.style['transform'] = 'translateX(-25%)';
} else {
innerProps.style['border-left-color'] = borderColor;
innerProps.style['transform'] = 'translateX(25%)';
}
}
/* istanbul ignore next */
{
var touchObj = this.touchManager.getTouchObject();
innerProps.on[touchObj.touchstart] = this.createScrollButtonEvent(type, touchObj);
}
return h(
'div',
wrapperProps,
[h('div', innerProps)]
);
},
createScrollButtonEvent: function createScrollButtonEvent(type, touchObj) {
var ctx = this;
var parent = getRealParent(ctx);
var _ctx$ops$scrollButton = ctx.ops.scrollButton,
step = _ctx$ops$scrollButton.step,
mousedownStep = _ctx$ops$scrollButton.mousedownStep;
var stepWithDirection = type == 'start' ? -step : step;
var mousedownStepWithDirection = type == 'start' ? -mousedownStep : mousedownStep;
var ref = requestAnimationFrame(window);
// bar props: type
var barType = ctx.type;
var isMouseDown = false;
var isMouseout = true;
var timeoutId = void 0;
function start(e) {
/* istanbul ignore if */
if (3 == e.which) {
return;
}
// set class hook
parent.setClassHook('cliking' + barType + type + 'Button', true);
e.stopImmediatePropagation();
e.preventDefault();
isMouseout = false;
parent.scrollBy(defineProperty({}, 'd' + ctx.bar.axis.toLowerCase(), stepWithDirection));
eventCenter(document, touchObj.touchend, endPress, false);
if (touchObj.touchstart == 'mousedown') {
var elm = ctx.$refs[type];
eventCenter(elm, 'mouseenter', enter, false);
eventCenter(elm, 'mouseleave', leave, false);
}
clearTimeout(timeoutId);
timeoutId = setTimeout(function () /* istanbul ignore next */{
isMouseDown = true;
ref(pressing, window);
}, 500);
}
function pressing() /* istanbul ignore next */{
if (isMouseDown && !isMouseout) {
parent.scrollBy(defineProperty({}, 'd' + ctx.bar.axis.toLowerCase(), mousedownStepWithDirection), false);
ref(pressing, window);
}
}
function endPress() {
clearTimeout(timeoutId);
isMouseDown = false;
eventCenter(document, touchObj.touchend, endPress, false, 'off');
if (touchObj.touchstart == 'mousedown') {
var elm = ctx.$refs[type];
eventCenter(elm, 'mouseenter', enter, false, 'off');
eventCenter(elm, 'mouseleave', leave, false, 'off');
}
parent.setClassHook('cliking' + barType + type + 'Button', false);
}
function enter() /* istanbul ignore next */{
isMouseout = false;
pressing();
}
function leave() /* istanbul ignore next */{
isMouseout = true;
}
return start;
}
}
};
function getBarData(vm, type) {
var axis = scrollMap[type].axis;
/** type.charAt(0) = vBar/hBar */
var barType = type.charAt(0) + 'Bar';
var hideBar = !vm.bar[barType].state.size || !vm.mergedOptions.scrollPanel['scrolling' + axis] || vm.refreshLoad && type !== 'vertical' || vm.mergedOptions.bar.disable;
var keepShowRail = vm.mergedOptions.rail.keepShow;
if (hideBar && !keepShowRail) {
return null;
}
return {
hideBar: hideBar,
props: {
type: type,
ops: {
bar: vm.mergedOptions.bar,
rail: vm.mergedOptions.rail,
scrollButton: vm.mergedOptions.scrollButton
},
state: vm.bar[barType].state,
hideBar: hideBar
},
on: {
setBarDrag: vm.setBarDrag
},
ref: type + 'Bar',
key: type
};
}
/**
* create bars
*
* @param {any} size
* @param {any} type
*/
function createBar(h, vm) {
var verticalBarProps = getBarData(vm, 'vertical');
var horizontalBarProps = getBarData(vm, 'horizontal');
// set class hooks
vm.setClassHook('hasVBar', !!(verticalBarProps && !verticalBarProps.hideBar));
vm.setClassHook('hasHBar', !!(horizontalBarProps && !horizontalBarProps.hideBar));
return [verticalBarProps ? h('bar', _extends({}, verticalBarProps, {
props: _extends({ otherBarHide: !horizontalBarProps }, verticalBarProps.props)
})) : null, horizontalBarProps ? h('bar', _extends({}, horizontalBarProps, {
props: _extends({ otherBarHide: !verticalBarProps }, horizontalBarProps.props)
})) : null];
}
/**
* This is like a HOC, It extracts the common parts of the
* native-mode, slide-mode and mix-mode.
* Each mode must implement the following methods:
* 1. refreshInternalStatus : use to refresh the component
* 2. destroy : Destroy some registryed events before component destroy.
* 3. updateBarStateAndEmitEvent: use to update bar states and emit events.
*/
var createComponent = function createComponent(_ref) {
var _render = _ref.render,
components = _ref.components,
mixins = _ref.mixins;
return {
name: 'vueScroll',
props: {
ops: { type: Object }
},
components: components,
mixins: [api].concat(toConsumableArray([].concat(mixins))),
created: function created() {
var _this = this;
/**
* Begin to merge options
*/
var _gfc = mergeObject(this.$vuescrollConfig || {}, {});
var ops = mergeObject(baseConfig, _gfc);
this.$options.propsData.ops = this.$options.propsData.ops || {};
Object.keys(this.$options.propsData.ops).forEach(function (key) {
{
defineReactive(_this.mergedOptions, key, _this.$options.propsData.ops);
}
});
// from ops to mergedOptions
mergeObject(ops, this.mergedOptions);
this._isVuescrollRoot = true;
this.renderError = validateOps(this.mergedOptions);
},
render: function render(h) {
var vm = this;
if (vm.renderError) {
return h('div', [[vm.$slots['default']]]);
}
if (!vm.touchManager) vm.touchManager = new touchManager();
// vuescroll data
var data = {
style: {
height: vm.vuescroll.state.height,
width: vm.vuescroll.state.width,
padding: 0,
position: 'relative',
overflow: 'hidden'
},
class: _extends({ __vuescroll: true }, vm.classHooks)
};
var touchObj = vm.touchManager.getTouchObject();
if (touchObj) {
var _data$on;
data.on = (_data$on = {}, defineProperty(_data$on, touchObj.touchenter, function () {
vm.vuescroll.state.pointerLeave = false;
vm.updateBarStateAndEmitEvent();
vm.setClassHook('mouseEnter', true);
}), defineProperty(_data$on, touchObj.touchleave, function () {
vm.vuescroll.state.pointerLeave = true;
vm.hideBar();
vm.setClassHook('mouseEnter', false);
}), defineProperty(_data$on, touchObj.touchmove, function () /* istanbul ignore next */{
vm.vuescroll.state.pointerLeave = false;
vm.updateBarStateAndEmitEvent();
}), _data$on);
}
var ch = [_render(h, vm)].concat(toConsumableArray(createBar(h, vm)));
var _customContainer = this.$slots['scroll-container'];
if (_customContainer) {
return insertChildrenIntoSlot(h, _customContainer, ch, data);
}
return h(
'div',
data,
[ch]
);
},
mounted: function mounted() {
var _this2 = this;
if (!this.renderError) {
this.initVariables();
this.initWatchOpsChange();
// Call external merged Api
this.refreshInternalStatus();
this.updatedCbs.push(function () {
_this2.scrollToAnchor();
// need to reflow to deal with the
// latest thing.
_this2.updateBarStateAndEmitEvent();
});
}
},
updated: function updated() {
var _this3 = this;
this.updatedCbs.forEach(function (cb) {
cb.call(_this3);
});
// Clear
this.updatedCbs = [];
},
beforeDestroy: function beforeDestroy() {
if (this.destroy) {
this.destroy();
}
},
/** ------------------------------- Computed ----------------------------- */
computed: {
scrollPanelElm: function scrollPanelElm() {
return this.$refs['scrollPanel']._isVue ? this.$refs['scrollPanel'].$el : this.$refs['scrollPanel'];
}
},
data: function data() {
return {
vuescroll: {
state: {
isDragging: false,
pointerLeave: true,
isRailHover: false,
/** Default sizeStrategies */
height: '100%',
width: '100%',
// current size strategy
currentSizeStrategy: 'percent',
currentScrollState: null,
currentScrollInfo: null
}
},
bar: {
vBar: {
state: {
posValue: 0,
size: 0,
opacity: 0
}
},
hBar: {
state: {
posValue: 0,
size: 0,
opacity: 0
}
}
},
mergedOptions: {
vuescroll: {},
scrollPanel: {},
scrollContent: {},
rail: {},
bar: {}
},
updatedCbs: [],
renderError: false,
classHooks: {
hasVBar: false,
hasHBar: false,
vBarVisible: false,
hBarVisible: false,
vBarDragging: false,
hBarDragging: false,
clikingVerticalStartButton: false,
clikingVerticalEndButton: false,
clikingHorizontalStartButton: false,
clikingHorizontalEndButton: false,
mouseEnter: false
}
};
},
/** ------------------------------- Methods -------------------------------- */
methods: {
/** ------------------------ Handlers --------------------------- */
scrollingComplete: function scrollingComplete() {
this.updateBarStateAndEmitEvent('handle-scroll-complete');
},
setBarDrag: function setBarDrag(val) {
/* istanbul ignore next */
this.vuescroll.state.isDragging = val;
},
setClassHook: function setClassHook(name, value) {
this.classHooks[name] = value;
},
/** ------------------------ Some Helpers --------------------------- */
/*
* To have a good ux, instead of hiding bar immediately, we hide bar
* after some seconds by using this simple debounce-hidebar method.
*/
showAndDefferedHideBar: function showAndDefferedHideBar(forceHideBar) {
var _this4 = this;
this.showBar();
if (this.timeoutId) {
clearTimeout(this.timeoutId);
this.timeoutId = 0;
}
this.timeoutId = setTimeout(function () {
_this4.timeoutId = 0;
_this4.hideBar(forceHideBar);
}, this.mergedOptions.bar.showDelay);
},
showBar: function showBar() {
var opacity = this.mergedOptions.bar.opacity;
this.bar.vBar.state.opacity = opacity;
this.bar.hBar.state.opacity = opacity;
},
hideBar: function hideBar(forceHideBar) {
var _vuescroll$state = this.vuescroll.state,
isDragging = _vuescroll$state.isDragging,
isRailHover = _vuescroll$state.isRailHover;
/* istanbul ignore next */
if (isDragging || isRailHover) {
return;
}
if (forceHideBar && !this.mergedOptions.bar.keepShow) {
this.bar.hBar.state.opacity = 0;
this.bar.vBar.state.opacity = 0;
}
// add isDragging condition
// to prevent from hiding bar while dragging the bar
if (!this.mergedOptions.bar.keepShow && !this.vuescroll.state.isDragging) {
this.bar.vBar.state.opacity = 0;
this.bar.hBar.state.opacity = 0;
}
},
useNumbericSize: function useNumbericSize() {
this.vuescroll.state.currentSizeStrategy = 'number';
var _mergedOptions$scroll = this.mergedOptions.scrollPanel,
maxHeight = _mergedOptions$scroll.maxHeight,
maxWidth = _mergedOptions$scroll.maxWidth;
var _$el$parentNode = this.$el.parentNode,
parentClientHeight = _$el$parentNode.clientHeight,
parentClientWidth = _$el$parentNode.clientWidth;
var _scrollPanelElm = this.scrollPanelElm,
scrollHeight = _scrollPanelElm.scrollHeight,
scrollWidth = _scrollPanelElm.scrollWidth;
var width = void 0;
var height = void 0;
if (maxHeight || maxWidth) {
height = scrollHeight <= maxHeight ? undefined : maxHeight;
width = scrollWidth <= maxWidth ? undefined : maxWidth;
} else {
height = parentClientHeight;
width = parentClientWidth;
}
this.vuescroll.state.height = height ? height + 'px' : undefined;
this.vuescroll.state.width = width ? width + 'px' : undefined;
},
usePercentSize: function usePercentSize() {
this.vuescroll.state.currentSizeStrategy = 'percent';
this.vuescroll.state.height = '100%';
this.vuescroll.state.width = '100%';
},
// Set its size to be equal to its parentNode
setVsSize: function setVsSize() {
var sizeStrategy = this.mergedOptions.vuescroll.sizeStrategy;
var _mergedOptions$scroll2 = this.mergedOptions.scrollPanel,
maxHeight = _mergedOptions$scroll2.maxHeight,
maxWidth = _mergedOptions$scroll2.maxWidth;
var _scrollPanelElm2 = this.scrollPanelElm,
clientHeight = _scrollPanelElm2.clientHeight,
clientWidth = _scrollPanelElm2.clientWidth;
if (sizeStrategy == 'number' || maxHeight && clientHeight > maxHeight || maxWidth && clientWidth > maxWidth) {
this.useNumbericSize();
} else if (sizeStrategy == 'percent' && clientHeight != maxHeight && clientWidth != maxWidth) {
this.usePercentSize();
}
},
/** ------------------------ Init --------------------------- */
initWatchOpsChange: function initWatchOpsChange() {
var _this5 = this;
var watchOpts = {
deep: true,
sync: true
};
this.$watch('mergedOptions', function () {
setTimeout(function () {
if (_this5.isSmallChangeThisTick) {
_this5.isSmallChangeThisTick = false;
_this5.updateBarStateAndEmitEvent('options-change');
return;
}
_this5.refreshInternalStatus();
}, 0);
}, watchOpts);
/**
* We also watch `small` changes, and when small changes happen, we send
* a signal to vuescroll, to tell it:
* 1. we don't need to registry resize
* 2. we don't need to registry scroller.
*/
smallChangeArray.forEach(function (opts) {
_this5.$watch(opts, function () {
_this5.isSmallChangeThisTick = true;
}, watchOpts);
});
},
// scrollTo hash-anchor while mounted component have mounted.
scrollToAnchor: function scrollToAnchor() /* istanbul ignore next */{
var validateHashSelector = function validateHashSelector(hash) {
return (/^#[a-zA-Z_]\d*$/.test(hash)
);
};
var hash = window.location.hash;
if (!hash || (hash = hash.slice(hash.lastIndexOf('#'))) && !validateHashSelector(hash)) {
return;
}
var elm = document.querySelector(hash);
if (!isChildInParent(elm, this.$el) || this.mergedOptions.scrollPanel.initialScrollY || this.mergedOptions.scrollPanel.initialScrollX) {
return;
}
this.scrollIntoView(elm);
}
/** ------------------------ Registry Resize --------------------------- */
}
};
};
// begin importing
var scrollPanel = {
name: 'scrollPanel',
props: { ops: { type: Object, required: true } },
methods: {
// trigger scrollPanel options initialScrollX,
// initialScrollY
updateInitialScroll: function updateInitialScroll() {
var x = 0;
var y = 0;
var parent = getRealParent(this);
if (this.ops.initialScrollX) {
x = this.ops.initialScrollX;
}
if (this.ops.initialScrollY) {
y = this.ops.initialScrollY;
}
if (x || y) {
parent.scrollTo({ x: x, y: y });
}
}
},
mounted: function mounted() {
var _this = this;
setTimeout(function () {
if (!_this._isDestroyed) {
_this.updateInitialScroll();
}
}, 0);
},
render: function render(h) {
// eslint-disable-line
var data = {
class: ['__panel'],
style: {
position: 'relative',
boxSizing: 'border-box'
}
};
var parent = getRealParent(this);
var _customPanel = parent.$slots['scroll-panel'];
if (_customPanel) {
return insertChildrenIntoSlot(h, _customPanel, this.$slots.default, data);
}
return h(
'div',
data,
[[this.$slots.default]]
);
}
};
/**
* Init following things
* 1. Component
* 2. Render
* 3. Config
*/
function _install(core, render) {
var _components;
var extraConfigs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
var extraValidators = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
var components = (_components = {}, defineProperty(_components, scrollPanel.name, scrollPanel), defineProperty(_components, bar.name, bar), _components);
var opts = {};
opts.components = components;
opts.render = render;
opts.mixins = core;
var comp = createComponent(opts);
// Init Config
extendOpts(extraConfigs, extraValidators);
return comp;
}
/**
* Get the children of parent those are in viewport
*/
function getCurrentViewportDom(parent, container) {
var children = parent.children;
var domFragment = [];
var isCurrentview = function isCurrentview(dom) {
var _dom$getBoundingClien = dom.getBoundingClientRect(),
left = _dom$getBoundingClien.left,
top = _dom$getBoundingClien.top,
width = _dom$getBoundingClien.width,
height = _dom$getBoundingClien.height;
var _container$getBoundin = container.getBoundingClientRect(),
parentLeft = _container$getBoundin.left,
parentTop = _container$getBoundin.top,
parentHeight = _container$getBoundin.height,
parentWidth = _container$getBoundin.width;
if (left - parentLeft + width > 0 && left - parentLeft < parentWidth && top - parentTop + height > 0 && top - parentTop < parentHeight) {
return true;
}
return false;
};
for (var i = 0; i < children.length; i++) {
var dom = children.item(i);
if (isCurrentview(dom) && !dom.isResizeElm) {
domFragment.push(dom);
}
}
return domFragment;
}
/**
* Compatible to scroller's animation function
*/
function createEasingFunction(easing, easingPattern) {
return function (time) {
return easingPattern(easing, time);
};
}
/**
* Calculate the easing pattern
* @link https://github.com/cferdinandi/smooth-scroll/blob/master/src/js/smooth-scroll.js
* modified by wangyi7099
* @param {String} type Easing pattern
* @param {Number} time Time animation should take to complete
* @returns {Number}
*/
function easingPattern(easing, time) {
var pattern = null;
/* istanbul ignore next */
{
// Default Easing Patterns
if (easing === 'easeInQuad') pattern = time * time; // accelerating from zero velocity
if (easing === 'easeOutQuad') pattern = time * (2 - time); // decelerating to zero velocity
if (easing === 'easeInOutQuad') pattern = time < 0.5 ? 2 * time * time : -1 + (4 - 2 * time) * time; // acceleration until halfway, then deceleration
if (easing === 'easeInCubic') pattern = time * time * time; // accelerating from zero velocity
if (easing === 'easeOutCubic') pattern = --time * time * time + 1; // decelerating to zero velocity
if (easing === 'easeInOutCubic') pattern = time < 0.5 ? 4 * time * time * time : (time - 1) * (2 * time - 2) * (2 * time - 2) + 1; // acceleration until halfway, then deceleration
if (easing === 'easeInQuart') pattern = time * time * time * time; // accelerating from zero velocity
if (easing === 'easeOutQuart') pattern = 1 - --time * time * time * time; // decelerating to zero velocity
if (easing === 'easeInOutQuart') pattern = time < 0.5 ? 8 * time * time * time * time : 1 - 8 * --time * time * time * time; // acceleration until halfway, then deceleration
if (easing === 'easeInQuint') pattern = time * time * time * time * time; // accelerating from zero velocity
if (easing === 'easeOutQuint') pattern = 1 + --time * time * time * time * time; // decelerating to zero velocity
if (easing === 'easeInOutQuint') pattern = time < 0.5 ? 16 * time * time * time * time * time : 1 + 16 * --time * time * time * time * time; // acceleration until halfway, then deceleration
}
return pattern || time; // no easing, no acceleration
}
function noop() {
return true;
}
/* istanbul ignore next */
var now = Date.now || function () {
return new Date().getTime();
};
var ScrollControl = function () {
function ScrollControl() {
classCallCheck(this, ScrollControl);
this.init();
this.isRunning = false;
}
createClass(ScrollControl, [{
key: 'pause',
value: function pause() {
/* istanbul ignore if */
if (!this.isRunning) return;
this.isPaused = true;
}
}, {
key: 'stop',
value: function stop() {
this.isStopped = true;
}
}, {
key: 'continue',
value: function _continue() {
/* istanbul ignore if */
if (!this.isPaused) return;
this.isPaused = false;
this.ts = now() - this.percent * this.spd;
this.execScroll();
}
}, {
key: 'startScroll',
value: function startScroll(st, ed, spd) {
var stepCb = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : noop;
var completeCb = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : noop;
var vertifyCb = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : noop;
var easingMethod = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : noop;
var df = ed - st;
var dir = df > 0 ? -1 : 1;
var nt = now();
if (!this.isRunning) {
this.init();
}
if (dir != this.dir || nt - this.ts > 200) {
this.ts = nt;
this.dir = dir;
this.st = st;
this.ed = ed;
this.df = df;
} /* istanbul ignore next */else {
this.df += df;
}
this.spd = spd;
this.completeCb = completeCb;
this.vertifyCb = vertifyCb;
this.stepCb = stepCb;
this.easingMethod = easingMethod;
if (!this.isRunning) this.execScroll();
}
}, {
key: 'execScroll',
value: function execScroll() {
var _this = this;
if (!this.df) return;
var percent = this.percent || 0;
this.percent = 0;
this.isRunning = true;
var loop = function loop() {
/* istanbul ignore if */
if (!_this.isRunning || !_this.vertifyCb(percent) || _this.isStopped) {
_this.isRunning = false;
return;
}
percent = (now() - _this.ts) / _this.spd;
if (_this.isPaused) {
_this.percent = percent;
_this.isRunning = false;
return;
}
if (percent < 1) {
var value = _this.st + _this.df * _this.easingMethod(percent);
_this.stepCb(value);
_this.ref(loop);
} else {
// trigger complete
_this.stepCb(_this.st + _this.df);
_this.completeCb();
_this.isRunning = false;
}
};
this.ref(loop);
}
}, {
key: 'init',
value: function init() {
this.st = 0;
this.ed = 0;
this.df = 0;
this.spd = 0;
this.ts = 0;
this.dir = 0;
this.ref = requestAnimationFrame(window);
this.isPaused = false;
this.isStopped = false;
}
}]);
return ScrollControl;
}();
function scrollTo(elm, x, y) {
var speed = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 300;
var easing = arguments[4];
var scrollingComplete = arguments[5];
var scrollLeft = void 0,
scrollTop = void 0,
scrollHeight = void 0,
scrollWidth = void 0,
clientWidth = void 0,
clientHeight = void 0;
var _elm = elm,
nodeType = _elm.nodeType;
var scrollX = new ScrollControl();
var scrollY = new ScrollControl();
if (!nodeType) {
warn('You must pass a dom for the first param, ' + 'for window scrolling, ' + 'you can pass document as the first param.');
return;
}
if (nodeType == 9) {
// document
elm = elm.scrollingElement;
}
var _elm2 = elm;
scrollLeft = _elm2.scrollLeft;
scrollTop = _elm2.scrollTop;
scrollHeight = _elm2.scrollHeight;
scrollWidth = _elm2.scrollWidth;
clientWidth = _elm2.clientWidth;
clientHeight = _elm2.clientHeight;
if (typeof x === 'undefined') {
x = scrollLeft;
} else {
x = getNumericValue(x, scrollWidth - clientWidth);
}
if (typeof y === 'undefined') {
y = scrollTop;
} else {
y = getNumericValue(y, scrollHeight - clientHeight);
}
var easingMethod = createEasingFunction(easing, easingPattern);
scrollX.startScroll(scrollLeft, x, speed, function (dx) {
elm.scrollLeft = dx;
}, scrollingComplete, undefined, easingMethod);
scrollY.startScroll(scrollTop, y, speed, function (dy) {
elm.scrollTop = dy;
}, scrollingComplete, undefined, easingMethod);
}
var api$1 = {
mounted: function mounted() {
// registry scroll
this.scrollX = new ScrollControl();
this.scrollY = new ScrollControl();
},
methods: {
nativeStop: function nativeStop() {
this.scrollX.stop();
this.scrollY.stop();
},
nativePause: function nativePause() {
this.scrollX.pause();
this.scrollY.pause();
},
nativeContinue: function nativeContinue() {
this.scrollX.continue();
this.scrollY.continue();
},
nativeScrollTo: function nativeScrollTo(x, y, speed, easing) {
if (speed === false) {
} else if (typeof speed === 'undefined') {
speed = this.mergedOptions.scrollPanel.speed;
}
var elm = this.scrollPanelElm;
var scrollTop = elm.scrollTop,
scrollLeft = elm.scrollLeft,
scrollWidth = elm.scrollWidth,
clientWidth = elm.clientWidth,
scrollHeight = elm.scrollHeight,
clientHeight = elm.clientHeight;
if (typeof x === 'undefined') {
x = scrollLeft;
} else {
x = getNumericValue(x, scrollWidth - clientWidth);
}
if (typeof y === 'undefined') {
y = scrollTop;
} else {
y = getNumericValue(y, scrollHeight - clientHeight);
}
if (speed) {
easing = easing || this.mergedOptions.scrollPanel.easing;
var easingMethod = createEasingFunction(easing, easingPattern);
if (x != scrollLeft) {
this.scrollX.startScroll(scrollLeft, x, speed, function (x) {
elm.scrollLeft = x;
}, this.scrollingComplete.bind(this), undefined, easingMethod);
}
if (y != scrollTop) {
this.scrollY.startScroll(scrollTop, y, speed, function (y) {
elm.scrollTop = y;
}, this.scrollingComplete.bind(this), undefined, easingMethod);
}
} else {
elm.scrollTop = y;
elm.scrollLeft = x;
}
},
getCurrentviewDomNative: function getCurrentviewDomNative() {
var parent = this.scrollContentElm;
var domFragment = getCurrentViewportDom(parent, this.$el);
return domFragment;
}
}
};
function getPanelData(context) {
// scrollPanel data start
var data = {
ref: 'scrollPanel',
style: {
height: '100%',
overflowY: 'scroll',
overflowX: 'scroll'
},
class: [],
nativeOn: {
'&scroll': context.handleScroll
},
props: {
ops: context.mergedOptions.scrollPanel
}
};
context.scrollYEnable = true;
context.scrollXEnable = true;
data.nativeOn.DOMMouseScroll = data.nativeOn.mousewheel = context.onMouseWheel;
var _context$mergedOption = context.mergedOptions.scrollPanel,
scrollingY = _context$mergedOption.scrollingY,
scrollingX = _context$mergedOption.scrollingX;
if (!context.bar.hBar.state.size || !scrollingX) {
context.scrollXEnable = false;
data.style.overflowX = 'hidden';
}
if (!context.bar.vBar.state.size || !scrollingY) {
context.scrollYEnable = false;
data.style.overflowY = 'hidden';
}
var gutter = getGutter();
/* istanbul ignore if */
if (!gutter) {
createHideBarStyle();
data.class.push('__hidebar');
if (isIos()) {
data.style['-webkit-overflow-scrolling'] = 'touch';
}
} else {
// hide system bar by use a negative value px
// gutter should be 0 when manually disable scrollingX #14
if (context.bar.vBar.state.size && context.mergedOptions.scrollPanel.scrollingY) {
if (context.mergedOptions.scrollPanel.verticalNativeBarPos == 'right') {
data.style.marginRight = '-' + gutter + 'px';
} /* istanbul ignore next */else {
data.style.marginLeft = '-' + gutter + 'px';
}
}
if (context.bar.hBar.state.size && context.mergedOptions.scrollPanel.scrollingX) {
data.style.height = 'calc(100% + ' + gutter + 'px)';
}
}
// clear legency styles of slide mode...
data.style.transformOrigin = '';
data.style.transform = '';
return data;
}
/**
* create a scrollPanel
*
* @param {any} size
* @param {any} context
* @returns
*/
function createPanel(h, context) {
var data = {};
data = getPanelData(context);
return h(
'scrollPanel',
data,
[getPanelChildren(h, context)]
);
}
function getPanelChildren(h, context) {
var viewStyle = {
position: 'relative',
'box-sizing': 'border-box',
'min-width': '100%',
'min-height': '100%'
};
var data = {
style: viewStyle,
ref: 'scrollContent',
class: '__view'
};
var _customContent = context.$slots['scroll-content'];
if (context.mergedOptions.scrollPanel.scrollingX) {
viewStyle.width = getComplitableStyle('width', 'fit-content');
} else {
data.style['width'] = '100%';
}
if (context.mergedOptions.scrollPanel.padding) {
data.style.paddingRight = context.mergedOptions.rail.size;
}
if (_customContent) {
return insertChildrenIntoSlot(h, _customContent, context.$slots.default, data);
}
return h(
'div',
data,
[context.$slots.default]
);
}
// detect content size change
function installResizeDetection(element, callback) {
return injectObject(element, callback);
}
function injectObject(element, callback) {
if (element.hasResized) {
return;
}
var OBJECT_STYLE = 'display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding: 0; margin: 0; opacity: 0; z-index: -1000; pointer-events: none;';
// define a wrap due to ie's zIndex bug
var objWrap = document.createElement('div');
objWrap.style.cssText = OBJECT_STYLE;
var object = document.createElement('object');
object.style.cssText = OBJECT_STYLE;
object.type = 'text/html';
object.tabIndex = -1;
object.onload = function () {
eventCenter(object.contentDocument.defaultView, 'resize', callback);
};
// https://github.com/wnr/element-resize-detector/blob/aafe9f7ea11d1eebdab722c7c5b86634e734b9b8/src/detection-strategy/object.js#L159
if (!isIE()) {
object.data = 'about:blank';
}
objWrap.isResizeElm = true;
objWrap.appendChild(object);
element.appendChild(objWrap);
if (isIE()) {
object.data = 'about:blank';
}
return function destroy() {
if (object.contentDocument) {
eventCenter(object.contentDocument.defaultView, 'resize', callback, 'off');
}
element.removeChild(objWrap);
element.hasResized = false;
};
}
/**
* These mixes is exclusive for native mode
*/
var update = {
methods: {
updateNativeModeBarState: function updateNativeModeBarState() {
var container = this.scrollPanelElm;
var isPercent = this.vuescroll.state.currentSizeStrategy == 'percent';
var _vuescroll$state = this.vuescroll.state,
width = _vuescroll$state.width,
height = _vuescroll$state.height;
var clientWidth = isPercent || !width ? container.clientWidth : width.slice(0, -2); // xxxpx ==> xxx
var clientHeight = isPercent || !height ? container.clientHeight : height.slice(0, -2);
var heightPercentage = clientHeight / container.scrollHeight;
var widthPercentage = clientWidth / container.scrollWidth;
this.bar.vBar.state.posValue = container.scrollTop * 100 / clientHeight;
this.bar.hBar.state.posValue = container.scrollLeft * 100 / clientWidth;
this.bar.vBar.state.size = heightPercentage < 1 ? heightPercentage : 0;
this.bar.hBar.state.size = widthPercentage < 1 ? widthPercentage : 0;
},
getNativePosition: function getNativePosition() {
return {
scrollTop: this.scrollPanelElm.scrollTop,
scrollLeft: this.scrollPanelElm.scrollLeft
};
},
css: function css(dom, style) /* istanbul ignore next */{
return window.getComputedStyle(dom)[style];
},
checkScrollable: function checkScrollable(e, dir, delta) /* istanbul ignore next */{
var scrollable = false;
// check mouse point scrollable.
var dom = e.target ? e.target : e;
while (dom && dom.nodeType == 1 && dom !== this.scrollPanelElm.parentNode && !/^BODY|HTML/.test(dom.nodeName)) {
var ov = (dir == 'dy' ? this.css(dom, 'overflowY') : this.css(dom, 'overflowX')) || this.css(dom, 'overflow') || '';
if (/scroll|auto/.test(ov)) {
var _getScrollProcess = this.getScrollProcess(dom),
v = _getScrollProcess.v,
h = _getScrollProcess.h;
if (dir == 'dx' && (delta < 0 && h > 0 || delta > 0 && h < 1) || dir == 'dy' && (delta < 0 && v > 0 || delta > 0 && v < 1)) {
scrollable = dom == this.scrollPanelElm;
break;
}
}
dom = dom.parentNode ? dom.parentNode : false;
}
return scrollable;
},
onMouseWheel: function onMouseWheel(event) /* istanbul ignore next */{
var duration = this.mergedOptions.vuescroll.wheelScrollDuration;
var isReverse = this.mergedOptions.vuescroll.wheelDirectionReverse;
var delta = 0;
var dir = void 0;
if (event.wheelDelta) {
if (event.deltaY) {
dir = 'dy';
delta = event.deltaY;
} else if (event.deltaX) {
delta = event.deltaX;
dir = 'dx';
} else {
delta = -1 * event.wheelDelta / 2;
}
} else if (event.detail) {
// horizontal scroll
if (event.axis == 1) {
dir = 'dx';
} else if (event.axis == 2) {
// vertical scroll
dir = 'dy';
}
delta = event.detail * 16;
}
if (event.shiftKey) {
dir = 'dx';
} else {
dir = 'dy';
}
if (isReverse) {
dir = dir == 'dx' ? 'dy' : 'dx';
}
if (this.checkScrollable(event, dir, delta)) {
event.stopPropagation();
event.preventDefault();
this.scrollBy(defineProperty({}, dir, delta), duration);
}
}
},
computed: {
scrollContentElm: function scrollContentElm() {
return this.$refs['scrollContent']._isVue ? this.$refs['scrollContent'].$el : this.$refs['scrollContent'];
}
}
};
var mixins = [api$1, update];
var core = {
mixins: mixins,
methods: {
destroy: function destroy() {
/* istanbul ignore next */
if (this.destroyResize) {
this.destroyResize();
}
},
getCurrentviewDom: function getCurrentviewDom() {
return this.getCurrentviewDomNative();
},
internalScrollTo: function internalScrollTo(destX, destY, animate, easing) {
this.nativeScrollTo(destX, destY, animate, easing);
},
internalStop: function internalStop() {
this.nativeStop();
},
internalPause: function internalPause() {
this.nativePause();
},
internalContinue: function internalContinue() {
this.nativeContinue();
},
handleScroll: function handleScroll(nativeEvent) {
this.updateBarStateAndEmitEvent('handle-scroll', nativeEvent);
},
updateBarStateAndEmitEvent: function updateBarStateAndEmitEvent(eventType) {
var nativeEvent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
this.updateNativeModeBarState();
if (eventType) {
this.emitEvent(eventType, nativeEvent);
}
if (this.mergedOptions.bar.onlyShowBarOnScroll) {
if (eventType == 'handle-scroll' || eventType == 'handle-resize' || eventType == 'refresh-status' || eventType == 'window-resize' || eventType == 'options-change') {
this.showAndDefferedHideBar(true /* forceHideBar: true */);
}
} else {
this.showAndDefferedHideBar();
}
},
getScrollProcess: function getScrollProcess(elm) {
var _ref = elm || this.scrollPanelElm,
scrollHeight = _ref.scrollHeight,
scrollWidth = _ref.scrollWidth,
clientHeight = _ref.clientHeight,
clientWidth = _ref.clientWidth,
scrollTop = _ref.scrollTop,
scrollLeft = _ref.scrollLeft;
var v = Math.min(scrollTop / (scrollHeight - clientHeight || 1), 1);
var h = Math.min(scrollLeft / (scrollWidth - clientWidth || 1), 1);
return {
v: v,
h: h
};
},
emitEvent: function emitEvent(eventType) {
var nativeEvent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var _scrollPanelElm = this.scrollPanelElm,
scrollTop = _scrollPanelElm.scrollTop,
scrollLeft = _scrollPanelElm.scrollLeft;
var vertical = {
type: 'vertical'
};
var horizontal = {
type: 'horizontal'
};
var _getScrollProcess = this.getScrollProcess(),
v = _getScrollProcess.v,
h = _getScrollProcess.h;
vertical.process = v;
horizontal.process = h;
vertical['barSize'] = this.bar.vBar.state.size;
horizontal['barSize'] = this.bar.hBar.state.size;
vertical['scrollTop'] = scrollTop;
horizontal['scrollLeft'] = scrollLeft;
this.$emit(eventType, vertical, horizontal, nativeEvent);
},
initVariables: function initVariables() {
this.$el._isVuescroll = true;
},
refreshInternalStatus: function refreshInternalStatus() {
// 1.set vuescroll height or width according to
// sizeStrategy
this.setVsSize();
// 2. registry resize event
this.registryResize();
// 3. update scrollbar's height/width
this.updateBarStateAndEmitEvent('refresh-status');
},
registryResize: function registryResize() {
var _this = this;
var resizeEnable = this.mergedOptions.vuescroll.detectResize;
/* istanbul ignore next */
if (this.destroyResize && resizeEnable) {
return;
}
if (this.destroyResize) {
this.destroyResize();
}
if (!resizeEnable) {
return;
}
var contentElm = this.scrollContentElm;
var vm = this;
var handleWindowResize = function handleWindowResize() /* istanbul ignore next */{
vm.updateBarStateAndEmitEvent('window-resize');
};
var handleDomResize = function handleDomResize() {
var currentSize = {};
currentSize['width'] = _this.scrollPanelElm.scrollWidth;
currentSize['height'] = _this.scrollPanelElm.scrollHeight;
_this.updateBarStateAndEmitEvent('handle-resize', currentSize);
// Since content sie changes, we should tell parent to set
// correct size to fit content's size
_this.setVsSize();
};
window.addEventListener('resize', handleWindowResize, false);
var destroyDomResize = installResizeDetection(contentElm, handleDomResize);
var destroyWindowResize = function destroyWindowResize() {
window.removeEventListener('resize', handleWindowResize, false);
};
this.destroyResize = function () {
destroyWindowResize();
destroyDomResize();
_this.destroyResize = null;
};
},
getPosition: function getPosition() {
return this.getNativePosition();
}
}
};
var config = {
vuescroll: {
wheelScrollDuration: 0,
wheelDirectionReverse: false
}
};
var component = _install(core, createPanel, [config]);
function install(Vue$$1) {
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
Vue$$1.component(opts.name || component.name, component);
Vue$$1.prototype.$vuescrollConfig = opts.ops || {};
}
var Vuescroll = _extends({
install: install,
version: '4.16.1',
refreshAll: refreshAll,
scrollTo: scrollTo
}, component);
/* istanbul ignore if */
if (typeof window !== 'undefined' && window.Vue) {
window.Vue.use(Vuescroll);
}
return Vuescroll;
})));