MDL-51803 core: sortable list, fix for touch devices

This commit is contained in:
Marina Glancy
2018-10-09 16:05:39 +02:00
parent b43f926b44
commit 261a3a3085
2 changed files with 34 additions and 9 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
+33 -8
View File
@@ -214,7 +214,7 @@ function($, log, autoScroll, str, ModalFactory, ModalEvents, Notification) {
*/
SortableList.prototype.dragStartHandler = function(evt) {
if (this.info !== null) {
if (this.info.type === 'click') {
if (this.info.type === 'click' || this.info.type === 'touchend') {
// Ignore double click.
return;
}
@@ -326,7 +326,7 @@ function($, log, autoScroll, str, ModalFactory, ModalEvents, Notification) {
evt.stopPropagation();
// Find the element that this draghandle belongs to.
var clickedElement = $(evt.currentTarget),
var clickedElement = $(evt.target).closest(this.config.moveHandlerSelector),
sourceList = clickedElement.closest(this.config.listSelector),
movedElement = clickedElement.closest(sourceList.children());
if (!movedElement.length) {
@@ -412,7 +412,11 @@ function($, log, autoScroll, str, ModalFactory, ModalEvents, Notification) {
var element = $(document.elementFromPoint(evt.clientX, evt.clientY));
// Find the list element and the list over the mouse position.
var current = element.closest('.' + CSS.targetListClass + ' > :not(.' + CSS.isDraggedClass + ')'),
var mainElement = this.info.element[0],
isNotSelf = function() {
return this !== mainElement;
},
current = element.closest('.' + CSS.targetListClass + ' > :not(.' + CSS.isDraggedClass + ')').filter(isNotSelf),
currentList = element.closest('.' + CSS.targetListClass),
proxy = this.proxy,
isNotProxy = function() {
@@ -437,11 +441,7 @@ function($, log, autoScroll, str, ModalFactory, ModalEvents, Notification) {
var parent = current.parent(),
ratio = this.isListHorizontal(parent) ? coordinates.xRatio : coordinates.yRatio,
subList = current.find('.' + CSS.targetListClass),
currentElement = this.info.element[0],
isNotCurrent = function() {
return this !== currentElement;
},
subListEmpty = !subList.children().filter(isNotProxy).filter(isNotCurrent).length;
subListEmpty = !subList.children().filter(isNotProxy).filter(isNotSelf).length;
if (subList.length && subListEmpty && ratio > 0.2 && ratio < 0.8) {
// This is an element that is a parent of an empty list and we are around the middle of this element.
// Treat it as if we are over this empty list.
@@ -462,11 +462,35 @@ function($, log, autoScroll, str, ModalFactory, ModalEvents, Notification) {
this.info.endY = evt.pageY;
this.info.endTime = new Date().getTime();
this.info.dropped = true;
this.info.positionChanged = this.hasPositionChanged(this.info);
var oldinfo = this.info;
this.executeCallback(SortableList.EVENTS.DROP);
this.finishDragging();
if (evt.type === 'touchend'
&& this.config.moveHandlerSelector !== null
&& (oldinfo.endTime - oldinfo.startTime < 500)
&& !oldinfo.positionChanged) {
// The click event is not triggered on touch screens because we call preventDefault in touchstart handler.
// If the touchend quickly followed touchstart without moving, consider it a "click".
this.clickHandler(evt);
}
}
};
/**
* Checks if the position of the dragged element in the list has changed
*
* @private
* @param {Object} info
* @return {Boolean}
*/
SortableList.prototype.hasPositionChanged = function(info) {
return info.sourceList[0] !== info.targetList[0] ||
info.sourceNextElement.length !== info.targetNextElement.length ||
(info.sourceNextElement.length && info.sourceNextElement[0] !== info.targetNextElement[0]);
};
/**
* Moves the current position of the dragged element
*
@@ -661,6 +685,7 @@ function($, log, autoScroll, str, ModalFactory, ModalEvents, Notification) {
e.stopPropagation();
this.moveElement($(e.currentTarget).data('parent-element'), $(e.currentTarget).data('before-element'));
this.info.endTime = new Date().getTime();
this.info.positionChanged = this.hasPositionChanged(this.info);
this.info.dropped = true;
clickedElement.focus();
this.executeCallback(SortableList.EVENTS.DROP);