update
This commit is contained in:
270
public/assets/libs/Sortable/plugins/AutoScroll/AutoScroll.js
Normal file
270
public/assets/libs/Sortable/plugins/AutoScroll/AutoScroll.js
Normal file
@@ -0,0 +1,270 @@
|
||||
import {
|
||||
on,
|
||||
off,
|
||||
css,
|
||||
throttle,
|
||||
cancelThrottle,
|
||||
scrollBy,
|
||||
getParentAutoScrollElement,
|
||||
expando,
|
||||
getRect,
|
||||
getWindowScrollingElement
|
||||
} from '../../src/utils.js';
|
||||
|
||||
import Sortable from '../../src/Sortable.js';
|
||||
|
||||
import { Edge, IE11OrLess, Safari } from '../../src/BrowserInfo.js';
|
||||
|
||||
let autoScrolls = [],
|
||||
scrollEl,
|
||||
scrollRootEl,
|
||||
scrolling = false,
|
||||
lastAutoScrollX,
|
||||
lastAutoScrollY,
|
||||
touchEvt,
|
||||
pointerElemChangedInterval;
|
||||
|
||||
function AutoScrollPlugin() {
|
||||
|
||||
function AutoScroll() {
|
||||
this.defaults = {
|
||||
scroll: true,
|
||||
scrollSensitivity: 30,
|
||||
scrollSpeed: 10,
|
||||
bubbleScroll: true
|
||||
};
|
||||
|
||||
// Bind all private methods
|
||||
for (let fn in this) {
|
||||
if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
|
||||
this[fn] = this[fn].bind(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AutoScroll.prototype = {
|
||||
dragStarted({ originalEvent }) {
|
||||
if (this.sortable.nativeDraggable) {
|
||||
on(document, 'dragover', this._handleAutoScroll);
|
||||
} else {
|
||||
if (this.options.supportPointer) {
|
||||
on(document, 'pointermove', this._handleFallbackAutoScroll);
|
||||
} else if (originalEvent.touches) {
|
||||
on(document, 'touchmove', this._handleFallbackAutoScroll);
|
||||
} else {
|
||||
on(document, 'mousemove', this._handleFallbackAutoScroll);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
dragOverCompleted({ originalEvent }) {
|
||||
// For when bubbling is canceled and using fallback (fallback 'touchmove' always reached)
|
||||
if (!this.options.dragOverBubble && !originalEvent.rootEl) {
|
||||
this._handleAutoScroll(originalEvent);
|
||||
}
|
||||
},
|
||||
|
||||
drop() {
|
||||
if (this.sortable.nativeDraggable) {
|
||||
off(document, 'dragover', this._handleAutoScroll);
|
||||
} else {
|
||||
off(document, 'pointermove', this._handleFallbackAutoScroll);
|
||||
off(document, 'touchmove', this._handleFallbackAutoScroll);
|
||||
off(document, 'mousemove', this._handleFallbackAutoScroll);
|
||||
}
|
||||
|
||||
clearPointerElemChangedInterval();
|
||||
clearAutoScrolls();
|
||||
cancelThrottle();
|
||||
},
|
||||
|
||||
nulling() {
|
||||
touchEvt =
|
||||
scrollRootEl =
|
||||
scrollEl =
|
||||
scrolling =
|
||||
pointerElemChangedInterval =
|
||||
lastAutoScrollX =
|
||||
lastAutoScrollY = null;
|
||||
|
||||
autoScrolls.length = 0;
|
||||
},
|
||||
|
||||
_handleFallbackAutoScroll(evt) {
|
||||
this._handleAutoScroll(evt, true);
|
||||
},
|
||||
|
||||
_handleAutoScroll(evt, fallback) {
|
||||
const x = (evt.touches ? evt.touches[0] : evt).clientX,
|
||||
y = (evt.touches ? evt.touches[0] : evt).clientY,
|
||||
|
||||
elem = document.elementFromPoint(x, y);
|
||||
|
||||
touchEvt = evt;
|
||||
|
||||
// IE does not seem to have native autoscroll,
|
||||
// Edge's autoscroll seems too conditional,
|
||||
// MACOS Safari does not have autoscroll,
|
||||
// Firefox and Chrome are good
|
||||
if (fallback || Edge || IE11OrLess || Safari) {
|
||||
autoScroll(evt, this.options, elem, fallback);
|
||||
|
||||
// Listener for pointer element change
|
||||
let ogElemScroller = getParentAutoScrollElement(elem, true);
|
||||
if (
|
||||
scrolling &&
|
||||
(
|
||||
!pointerElemChangedInterval ||
|
||||
x !== lastAutoScrollX ||
|
||||
y !== lastAutoScrollY
|
||||
)
|
||||
) {
|
||||
pointerElemChangedInterval && clearPointerElemChangedInterval();
|
||||
// Detect for pointer elem change, emulating native DnD behaviour
|
||||
pointerElemChangedInterval = setInterval(() => {
|
||||
let newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true);
|
||||
if (newElem !== ogElemScroller) {
|
||||
ogElemScroller = newElem;
|
||||
clearAutoScrolls();
|
||||
}
|
||||
autoScroll(evt, this.options, newElem, fallback);
|
||||
}, 10);
|
||||
lastAutoScrollX = x;
|
||||
lastAutoScrollY = y;
|
||||
}
|
||||
} else {
|
||||
// if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll
|
||||
if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) {
|
||||
clearAutoScrolls();
|
||||
return;
|
||||
}
|
||||
autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return Object.assign(AutoScroll, {
|
||||
pluginName: 'scroll',
|
||||
initializeByDefault: true
|
||||
});
|
||||
}
|
||||
|
||||
function clearAutoScrolls() {
|
||||
autoScrolls.forEach(function(autoScroll) {
|
||||
clearInterval(autoScroll.pid);
|
||||
});
|
||||
autoScrolls = [];
|
||||
}
|
||||
|
||||
function clearPointerElemChangedInterval() {
|
||||
clearInterval(pointerElemChangedInterval);
|
||||
}
|
||||
|
||||
|
||||
const autoScroll = throttle(function(evt, options, rootEl, isFallback) {
|
||||
// Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
|
||||
if (!options.scroll) return;
|
||||
const x = (evt.touches ? evt.touches[0] : evt).clientX,
|
||||
y = (evt.touches ? evt.touches[0] : evt).clientY,
|
||||
sens = options.scrollSensitivity,
|
||||
speed = options.scrollSpeed,
|
||||
winScroller = getWindowScrollingElement();
|
||||
|
||||
let scrollThisInstance = false,
|
||||
scrollCustomFn;
|
||||
|
||||
// New scroll root, set scrollEl
|
||||
if (scrollRootEl !== rootEl) {
|
||||
scrollRootEl = rootEl;
|
||||
|
||||
clearAutoScrolls();
|
||||
|
||||
scrollEl = options.scroll;
|
||||
scrollCustomFn = options.scrollFn;
|
||||
|
||||
if (scrollEl === true) {
|
||||
scrollEl = getParentAutoScrollElement(rootEl, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let layersOut = 0;
|
||||
let currentParent = scrollEl;
|
||||
do {
|
||||
let el = currentParent,
|
||||
rect = getRect(el),
|
||||
|
||||
top = rect.top,
|
||||
bottom = rect.bottom,
|
||||
left = rect.left,
|
||||
right = rect.right,
|
||||
|
||||
width = rect.width,
|
||||
height = rect.height,
|
||||
|
||||
canScrollX,
|
||||
canScrollY,
|
||||
|
||||
scrollWidth = el.scrollWidth,
|
||||
scrollHeight = el.scrollHeight,
|
||||
|
||||
elCSS = css(el),
|
||||
|
||||
scrollPosX = el.scrollLeft,
|
||||
scrollPosY = el.scrollTop;
|
||||
|
||||
|
||||
if (el === winScroller) {
|
||||
canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible');
|
||||
canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible');
|
||||
} else {
|
||||
canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll');
|
||||
canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll');
|
||||
}
|
||||
|
||||
let vx = canScrollX && (Math.abs(right - x) <= sens && (scrollPosX + width) < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX);
|
||||
let vy = canScrollY && (Math.abs(bottom - y) <= sens && (scrollPosY + height) < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY);
|
||||
|
||||
|
||||
if (!autoScrolls[layersOut]) {
|
||||
for (let i = 0; i <= layersOut; i++) {
|
||||
if (!autoScrolls[i]) {
|
||||
autoScrolls[i] = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) {
|
||||
autoScrolls[layersOut].el = el;
|
||||
autoScrolls[layersOut].vx = vx;
|
||||
autoScrolls[layersOut].vy = vy;
|
||||
|
||||
clearInterval(autoScrolls[layersOut].pid);
|
||||
|
||||
if (vx != 0 || vy != 0) {
|
||||
scrollThisInstance = true;
|
||||
/* jshint loopfunc:true */
|
||||
autoScrolls[layersOut].pid = setInterval((function () {
|
||||
// emulate drag over during autoscroll (fallback), emulating native DnD behaviour
|
||||
if (isFallback && this.layer === 0) {
|
||||
Sortable.active._onTouchMove(touchEvt); // To move ghost if it is positioned absolutely
|
||||
}
|
||||
let scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0;
|
||||
let scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0;
|
||||
|
||||
if (typeof(scrollCustomFn) === 'function') {
|
||||
if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt, autoScrolls[this.layer].el) !== 'continue') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY);
|
||||
}).bind({layer: layersOut}), 24);
|
||||
}
|
||||
}
|
||||
layersOut++;
|
||||
} while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false)));
|
||||
scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not
|
||||
}, 30);
|
||||
|
||||
export default AutoScrollPlugin;
|
||||
80
public/assets/libs/Sortable/plugins/AutoScroll/README.md
Normal file
80
public/assets/libs/Sortable/plugins/AutoScroll/README.md
Normal file
@@ -0,0 +1,80 @@
|
||||
## AutoScroll
|
||||
This plugin allows for the page to automatically scroll during dragging near a scrollable element's edge on mobile devices and IE9 (or whenever fallback is enabled), and also enhances most browser's native drag-and-drop autoscrolling.
|
||||
Demo:
|
||||
- `window`: https://jsbin.com/dosilir/edit?js,output
|
||||
- `overflow: hidden`: https://jsbin.com/xecihez/edit?html,js,output
|
||||
|
||||
**This plugin is a default plugin, and is included in the default UMD and ESM builds of Sortable**
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
### Mounting
|
||||
```js
|
||||
import { Sortable, AutoScroll } from 'sortablejs';
|
||||
|
||||
Sortable.mount(new AutoScroll());
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
### Options
|
||||
|
||||
```js
|
||||
new Sortable(el, {
|
||||
scroll: true, // Enable the plugin. Can be HTMLElement.
|
||||
scrollFn: function(offsetX, offsetY, originalEvent, touchEvt, hoverTargetEl) { ... }, // if you have custom scrollbar scrollFn may be used for autoscrolling
|
||||
scrollSensitivity: 30, // px, how near the mouse must be to an edge to start scrolling.
|
||||
scrollSpeed: 10, // px, speed of the scrolling
|
||||
bubbleScroll: true // apply autoscroll to all parent elements, allowing for easier movement
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
#### `scroll` option
|
||||
Enables the plugin. Defaults to `true`. May also be set to an HTMLElement which will be where autoscrolling is rooted.
|
||||
|
||||
Demo:
|
||||
- `window`: https://jsbin.com/dosilir/edit?js,output
|
||||
- `overflow: hidden`: https://jsbin.com/xecihez/edit?html,js,output
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
#### `scrollFn` option
|
||||
Defines function that will be used for autoscrolling. el.scrollTop/el.scrollLeft is used by default.
|
||||
Useful when you have custom scrollbar with dedicated scroll function.
|
||||
This function should return `'continue'` if it wishes to allow Sortable's native autoscrolling.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
#### `scrollSensitivity` option
|
||||
Defines how near the mouse must be to an edge to start scrolling.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
#### `scrollSpeed` option
|
||||
The speed at which the window should scroll once the mouse pointer gets within the `scrollSensitivity` distance.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
#### `bubbleScroll` option
|
||||
If set to `true`, the normal `autoscroll` function will also be applied to all parent elements of the element the user is dragging over.
|
||||
|
||||
Demo: https://jsbin.com/kesewor/edit?html,js,output
|
||||
|
||||
|
||||
---
|
||||
1
public/assets/libs/Sortable/plugins/AutoScroll/index.js
Normal file
1
public/assets/libs/Sortable/plugins/AutoScroll/index.js
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from './AutoScroll.js';
|
||||
Reference in New Issue
Block a user