Files
FHC-Core/public/js/directives/drop.js
T
2025-09-11 14:58:20 +02:00

78 lines
1.9 KiB
JavaScript

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;
}
}