Files
pyrom/data/static/js/ui.js

98 lines
3.1 KiB
JavaScript

'use strict';
{
function isBefore(el1, el2) {
if (el2.parentNode === el1.parentNode) {
for (let cur = el1.previousSibling; cur; cur = cur.previousSibling) {
if (cur === el2) return true;
}
}
return false;
}
let draggedItem = null;
function sortableItemDragStart(e, item) {
const box = item.getBoundingClientRect();
const oX = e.clientX - box.left;
const oY = e.clientY - box.top;
draggedItem = item;
item.classList.add('contrast-bg');
e.dataTransfer.setDragImage(item, oX, oY);
e.dataTransfer.effectAllowed = 'move';
}
function sortableItemDragEnd(e, item) {
draggedItem = null;
item.classList.remove('contrast-bg');
}
function sortableItemDragOver(e, item) {
const target = e.target.closest('.sortable-item');
if (!target || target === draggedItem) {
return;
}
const inSameList = draggedItem.dataset.sortableListKey === target.dataset.sortableListKey;
if (!inSameList) {
return;
}
const targetList = draggedItem.closest('.sortable-list');
if (isBefore(draggedItem, target)) {
targetList.insertBefore(draggedItem, target);
} else {
targetList.insertBefore(draggedItem, target.nextSibling);
}
}
const listItemsHandled = new Map();
const getListItemsHandled = (list) => {
return listItemsHandled.get(list) || new Set();
}
function registerSortableList(list) {
list.querySelectorAll('li:not(.immovable)').forEach(item => {
const listItems = getListItemsHandled(list);
listItems.add(item);
listItemsHandled.set(list, listItems);
const dragger = item.querySelector('.dragger');
dragger.addEventListener('dragstart', e => { sortableItemDragStart(e, item) });
dragger.addEventListener('dragend', e => { sortableItemDragEnd(e, item) });
item.addEventListener('dragover', e => { sortableItemDragOver(e, item) });
});
const obs = new MutationObserver(records => {
for (const mutation of records) {
mutation.addedNodes.forEach(node => {
if (!(node instanceof HTMLElement)) return;
if (!node.classList.contains('sortable-item')) return;
const listItems = getListItemsHandled(list);
if (listItems.has(node)) return;
const dragger = node.querySelector('.dragger');
dragger.addEventListener('dragstart', e => { sortableItemDragStart(e, item) });
dragger.addEventListener('dragend', e => { sortableItemDragEnd(e, item) });
node.addEventListener('dragover', e => { sortableItemDragOver(e, node) });
listItems.add(node);
listItemsHandled.set(list, listItems);
});
}
});
obs.observe(list, { childList: true });
}
document.querySelectorAll('.sortable-list').forEach(registerSortableList);
const listsObs = new MutationObserver(records => {
for (const mutation of records) {
mutation.addedNodes.forEach(node => {
if (!(node instanceof HTMLElement)) return;
if (!node.classList.contains('sortable-list')) return;
registerSortableList(node);
});
}
});
listsObs.observe(document.body, { childList: true, subtree: true })
}