public/src/js/modules/droppable.js (142 lines of code) (raw):

import ko from 'knockout'; import _ from 'underscore'; import BaseClass from 'models/base-class'; import copiedArticle from 'modules/copied-article'; import alert from 'utils/alert'; import * as draggableElement from 'utils/draggable-element'; import dispatch from 'utils/drag-dispatcher'; import mediator from 'utils/mediator'; var sourceGroup; const listeners = Object.freeze({ dragstart: function (element, event) { var sourceItem = ko.dataFor(event.target); if (_.isFunction(sourceItem.get)) { event.dataTransfer.setData('sourceItem', JSON.stringify(sourceItem.get())); } sourceGroup = ko.dataFor(element); }, dragover: function (element, event) { var targetGroup = ko.dataFor(element), targetItem = getTargetItem(event.target); event.preventDefault(); event.stopPropagation(); targetGroup.setAsTarget(targetItem, !!event.ctrlKey); }, dragleave: function (element, event) { var targetGroup = ko.dataFor(element); event.preventDefault(); event.stopPropagation(); targetGroup.unsetAsTarget(); }, drop: function (element, event) { var targetGroup = ko.dataFor(element), targetItem = getTargetItem(event.target), source; if (!targetGroup) { return; } try { source = draggableElement.getItem(event.dataTransfer, sourceGroup); } catch (ex) { targetGroup.unsetAsTarget(); alert(ex.message); return; } event.preventDefault(); event.stopPropagation(); copiedArticle.flush(); targetGroup.unsetAsTarget(); return dispatch(source, targetItem, targetGroup, !!event.ctrlKey); } }); const imageEditorListeners = Object.freeze({ drop: function (element, event) { var bindingContext = ko.dataFor(event.target); event.preventDefault(); event.stopPropagation(); var action = bindingContext.dropInEditor(event.dataTransfer); bindingContext.underDrag(false); return action; }, dragover: function (element, event) { var bindingContext = ko.dataFor(event.target); event.preventDefault(); event.stopPropagation(); bindingContext.underDrag(true); }, dragleave: function (element, event) { var bindingContext = ko.dataFor(event.target); event.preventDefault(); event.stopPropagation(); bindingContext.underDrag(false); }, dragstart: function (element, event) { var bindingContext = ko.dataFor(event.target); event.dataTransfer.setData('sourceMeta', JSON.stringify(bindingContext.meta())); } }); export default class Droppable extends BaseClass { static get listeners() { return listeners; } static get imageEditor() { return imageEditorListeners; } constructor() { super(); function getListener (name, element) { return function (event) { listeners[name](element, event); }; } function getEditorListener (name, element) { return function (event) { imageEditorListeners[name](element, event); }; } window.addEventListener('dragover', preventDefaultAction, false); window.addEventListener('drop', preventDefaultAction, false); this.listenOn(mediator, 'drop', (...args) => { dispatch(...args); }); ko.bindingHandlers.makeDroppable = { init: function (element) { for (var eventName in listeners) { element.addEventListener(eventName, getListener(eventName, element), false); } } }; ko.bindingHandlers.makeDraggable = { init: function (element) { element.addEventListener('dragstart', getListener('dragstart', element), false); } }; ko.bindingHandlers.dropImage = { init: function(el, valueAccessor) { var isDropEnabled = ko.unwrap(valueAccessor()); if (isDropEnabled) { for (var eventName in imageEditorListeners) { el.addEventListener(eventName, getEditorListener(eventName, el), false); } } } }; } dispose() { super.dispose(); window.removeEventListener('dragover', preventDefaultAction); window.removeEventListener('drop', preventDefaultAction); } } function getTargetItem (target, context) { context = context || ko.contextFor(target); var data = context.$data || {}; if (!data.dropTarget && context.$parentContext) { return getTargetItem(null, context.$parentContext); } else { return data; } } function preventDefaultAction (event) { event.preventDefault(); }