import { getValidTransferData, eventHasTypes, bindDragEnterLeave } from '../helpers/DragAndDrop.js'; const EFFECTS = [ 'move', 'copy', 'link', 'none' ]; export default { mounted(el, binding) { const allowedTypes = Object.keys(binding.modifiers); allowedTypes.forEach(type => { if (type.substr(-11) == '-collection') { const singleType = type.substr(0, type.length-11); if (!allowedTypes.includes(singleType)) allowedTypes.push(singleType); } }); const strict = binding.arg.match(/(strict-|-strict)/); const arg = binding.arg.replace(/(strict-|-strict)/, ''); const effect = EFFECTS.includes(arg) ? arg : null; const bcc = new BroadcastChannel('fhc-dnd'); let allowed = false; function onEnter(evt) { allowed = eventHasTypes(evt, allowedTypes, strict); if (allowed) { evt.preventDefault(); bcc.postMessage('block'); } } function onLeave(evt, wasDropped) { if (allowed && !wasDropped) { bcc.postMessage('release'); } } function onOver(evt) { if (allowed) { evt.preventDefault(); if (effect) evt.dataTransfer.dropEffect = effect; } } function onDrop(evt) { let result = getValidTransferData(evt, allowedTypes, strict); if (!Array.isArray(result) && !binding.modifiers[result.type] && allowedTypes.includes(result.type + '-collection')) result = [result]; const res = binding.value(evt, result); if (res instanceof Promise) { res.then(r => { bcc.postMessage('release'); return r; }); } else { bcc.postMessage('release'); } } const cleanupEnterLeave = bindDragEnterLeave(el, onEnter, onLeave); el.addEventListener('dragover', onOver); el.addEventListener('drop', onDrop); el.fhcDropCleanup = () => { cleanupEnterLeave(); el.removeEventListener('dragover', onOver); el.removeEventListener('drop', onDrop); }; }, beforeUnmount(el) { el.fhcDropCleanup(); delete el.fhcDropCleanup; } }