From 5b986b7bb089cc630db427dcd313b4d2e26c88d1 Mon Sep 17 00:00:00 2001 From: djmaze Date: Sun, 27 Sep 2020 12:04:47 +0200 Subject: [PATCH] Bugfix: Chrome 84 on Android only accepts text/plain in Drag & Drop --- dev/External/User/ko.js | 12 ++++---- vendors/inputosaurus/.code-changed | 0 vendors/inputosaurus/inputosaurus.js | 44 ++++++++++++++++++---------- 3 files changed, 35 insertions(+), 21 deletions(-) delete mode 100644 vendors/inputosaurus/.code-changed diff --git a/dev/External/User/ko.js b/dev/External/User/ko.js index 014d0733f..b2e526b28 100644 --- a/dev/External/User/ko.js +++ b/dev/External/User/ko.js @@ -2,15 +2,16 @@ const ko = window.ko, rlContentType = 'snappymail/action', - // In Chrome we have no access to getData unless it's the 'drop' event - getDragAction = e => dragData && e.dataTransfer.types.includes(rlContentType) ? dragData.action : false, + // In Chrome we have no access to dataTransfer.getData unless it's the 'drop' event + // In Chrome Mobile dataTransfer.types.includes(rlContentType) fails, only text/plain is set + getDragAction = () => dragData ? dragData.action : false, setDragAction = (e, action, effect, data, img) => { dragData = { action: action, data: data }; - e.dataTransfer.setData(rlContentType, action); - e.dataTransfer.setData('Text', rlContentType+'/'+action); +// e.dataTransfer.setData(rlContentType, action); + e.dataTransfer.setData('text/plain', rlContentType+'/'+action); e.dataTransfer.setDragImage(img, 0, 0); e.dataTransfer.effectAllowed = effect; }, @@ -205,10 +206,12 @@ ko.bindingHandlers.sortableItem = { element.addEventListener("dragend", e => { element.style.opacity = null; if ('sortable' === getDragAction(e)) { + dragData.data.style.cssText = ''; let row = parent.rows[options.list.indexOf(ko.dataFor(element))]; if (row != dragData.data) { row.before(dragData.data); } + dragData = null; } }); if (!parent.sortable) { @@ -217,7 +220,6 @@ ko.bindingHandlers.sortableItem = { parent.addEventListener("dragover", fnHover); parent.addEventListener("drop", e => { if ('sortable' === getDragAction(e)) { - dragData.data.style.opacity = null; e.preventDefault(); let data = ko.dataFor(dragData.data), from = options.list.indexOf(data), diff --git a/vendors/inputosaurus/.code-changed b/vendors/inputosaurus/.code-changed deleted file mode 100644 index e69de29bb..000000000 diff --git a/vendors/inputosaurus/inputosaurus.js b/vendors/inputosaurus/inputosaurus.js index 8df3e4486..c57db8d89 100644 --- a/vendors/inputosaurus/inputosaurus.js +++ b/vendors/inputosaurus/inputosaurus.js @@ -23,23 +23,26 @@ const doc = document, datalist = createEl('datalist',{id:"inputosaurus-datalist"}), fakeSpan = createEl('span',{class:"inputosaurus-fake-span"}), - contentType = 'application/x-inputosaurus-item', - getTransferData = data => 'move' === data.dropEffect && data.getData(contentType); + contentType = 'inputosaurus/item'; doc.body.append(fakeSpan, datalist); -let removeDragged = null; +let dragData; window.Inputosaurus = class { constructor(element, options) { var self = this, - els = {}; + els = {}, + // In Chrome we have no access to dataTransfer.getData unless it's the 'drop' event + // In Chrome Mobile dataTransfer.types.includes(contentType) fails, only text/plain is set + validDropzone = () => dragData && dragData.li.parentNode !== els.ul, + fnDrag = e => validDropzone(e) && e.preventDefault(); self.element = element; - self._focusTriggerTimer = 0; + self._focusTimer = 0; self.options = Object.assign({ @@ -66,12 +69,13 @@ window.Inputosaurus = class { // Create the elements els.ul = createEl('ul',{class:"inputosaurus-container"}); - els.ul.addEventListener("dragover", e => getTransferData(e.dataTransfer) && e.preventDefault()); + els.ul.addEventListener("dragenter", fnDrag); + els.ul.addEventListener("dragover", fnDrag); els.ul.addEventListener("drop", e => { - let value = getTransferData(e.dataTransfer); - if (value) { - els.input.value = value; - removeDragged(); + if (validDropzone(e) && dragData.value) { + e.preventDefault(); + dragData.source._removeDraggedTag(dragData.li); + els.input.value = dragData.value; self.parseInput(); } }); @@ -132,8 +136,8 @@ window.Inputosaurus = class { _focusTrigger(bValue) { var self = this; - clearTimeout(self._focusTriggerTimer); - self._focusTriggerTimer = setTimeout(() => { + clearTimeout(self._focusTimer); + self._focusTimer = setTimeout(() => { self.elements.ul.classList.toggle('inputosaurus-focused', bValue); self.options.focusCallback(bValue); }, 10); @@ -400,13 +404,21 @@ window.Inputosaurus = class { li.inputosaurusValue = v.obj.toLine(false, false, false); li.addEventListener("dragstart", e => { - e.dataTransfer.setData(contentType, li.inputosaurusValue); - e.dataTransfer.setDragImage(li, 0, 0); + dragData = { + source: self, + li: li, + value: li.inputosaurusValue + }; +// e.dataTransfer.setData(contentType, li.inputosaurusValue); + e.dataTransfer.setData('text/plain', contentType); +// e.dataTransfer.setDragImage(li, 0, 0); e.dataTransfer.effectAllowed = 'move'; li.style.opacity = 0.25; - removeDragged = () => self._removeDraggedTag(li); }); - li.addEventListener("dragend", () => li.style.opacity = null); + li.addEventListener("dragend", () => { + dragData = null; + li.style.cssText = ''; + }); els.inputCont.before(li); }