diff --git a/services/web/frontend/js/features/file-tree/components/file-tree-folder-list.js b/services/web/frontend/js/features/file-tree/components/file-tree-folder-list.js index ea95e0b215..05ee3d2fa2 100644 --- a/services/web/frontend/js/features/file-tree/components/file-tree-folder-list.js +++ b/services/web/frontend/js/features/file-tree/components/file-tree-folder-list.js @@ -19,6 +19,7 @@ function FileTreeFolderList({ className={classNames('list-unstyled', classes.root)} role="tree" ref={dropRef} + dnd-container="true" > {folders.sort(compareFunction).map(folder => { return ( diff --git a/services/web/frontend/js/features/file-tree/contexts/file-tree-draggable.js b/services/web/frontend/js/features/file-tree/contexts/file-tree-draggable.js index 21017d492b..3eb793cc8a 100644 --- a/services/web/frontend/js/features/file-tree/contexts/file-tree-draggable.js +++ b/services/web/frontend/js/features/file-tree/contexts/file-tree-draggable.js @@ -14,7 +14,44 @@ import { useFileTreeActionable } from './file-tree-actionable' import { useFileTreeMutable } from './file-tree-mutable' import { useFileTreeSelectable } from '../contexts/file-tree-selectable' -const DndContext = createDndContext(HTML5Backend) +// HACK ALERT +// DnD binds drag and drop events on window and stop propagation if the dragged +// item is not a DnD element. This break other drag and drop interfaces; in +// particular in rich text. +// This is a hacky workaround to avoid calling the DnD listeners when the +// draggable or droppable element is not within a `dnd-container` element. +const ModifiedBackend = (...args) => { + function isDndChild(elt) { + if (elt.getAttribute && elt.getAttribute('dnd-container')) return true + if (!elt.parentNode) return false + return isDndChild(elt.parentNode) + } + const instance = new HTML5Backend(...args) + + const dragDropListeners = [ + 'handleTopDragStart', + 'handleTopDragStartCapture', + 'handleTopDragEndCapture', + 'handleTopDragEnter', + 'handleTopDragEnterCapture', + 'handleTopDragLeaveCapture', + 'handleTopDragOver', + 'handleTopDragOverCapture', + 'handleTopDrop', + 'handleTopDropCapture' + ] + + dragDropListeners.forEach(dragDropListener => { + const originalListener = instance[dragDropListener] + instance[dragDropListener] = (ev, ...extraArgs) => { + if (isDndChild(ev.target)) originalListener(ev, ...extraArgs) + } + }) + + return instance +} + +const DndContext = createDndContext(ModifiedBackend) const DRAGGABLE_TYPE = 'ENTITY'