Skip to content

Commit c40d089

Browse files
committed
feat: svg elements drag drop feature
1 parent 92a6fd5 commit c40d089

File tree

1 file changed

+66
-21
lines changed

1 file changed

+66
-21
lines changed

src/LiveDevelopment/BrowserScripts/RemoteFunctions.js

Lines changed: 66 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,6 +1529,26 @@ function RemoteFunctions(config = {}) {
15291529
return null;
15301530
}
15311531

1532+
function onDragStart(event, element) {
1533+
event.stopPropagation();
1534+
event.dataTransfer.setData("text/plain", element.getAttribute(GLOBALS.DATA_BRACKETS_ID_ATTR));
1535+
_dragStartChores(element);
1536+
_clearDropMarkers();
1537+
window._currentDraggedElement = element;
1538+
dismissUIAndCleanupState();
1539+
dismissImageRibbonGallery();
1540+
event.dataTransfer.effectAllowed = "move";
1541+
}
1542+
1543+
function onDragEnd(event, element) {
1544+
event.preventDefault();
1545+
event.stopPropagation();
1546+
_dragEndChores(element);
1547+
_clearDropMarkers();
1548+
_stopAutoScroll();
1549+
delete window._currentDraggedElement;
1550+
}
1551+
15321552
/**
15331553
* Handle dragover events on the document (throttled version)
15341554
* Shows drop markers on valid drop targets
@@ -1689,6 +1709,39 @@ function RemoteFunctions(config = {}) {
16891709
delete window._currentDraggedElement;
16901710
}
16911711

1712+
/**
1713+
* this functions are mainly for handling SVG elements dragging
1714+
* as the draggable property doesn't work on them. so we add mousedown, mouseup, mousemove related listeners
1715+
* and internally we call the drag functions
1716+
*/
1717+
function onDragMouseDown(event, element) {
1718+
event.preventDefault();
1719+
event.stopPropagation();
1720+
1721+
window._currentDraggedElement = element;
1722+
_dragStartChores(element);
1723+
_clearDropMarkers();
1724+
dismissUIAndCleanupState();
1725+
dismissImageRibbonGallery();
1726+
1727+
window._isDraggingSVG = true;
1728+
}
1729+
1730+
function onDragMouseUp(event) {
1731+
if (window._isDraggingSVG) {
1732+
event.preventDefault();
1733+
onDrop(event);
1734+
delete window._isDraggingSVG;
1735+
}
1736+
}
1737+
1738+
function onDragMouseMove(event) {
1739+
if (window._isDraggingSVG) {
1740+
event.preventDefault();
1741+
onDragOver(event);
1742+
}
1743+
}
1744+
16921745
/**
16931746
* this function is to check if an element should show the edit text option
16941747
* it is needed because edit text option doesn't make sense with many elements like images, videos, hr tag etc
@@ -2082,28 +2135,16 @@ function RemoteFunctions(config = {}) {
20822135
// disable dragging on all elements and then enable it on the current element
20832136
const allElements = document.querySelectorAll(`[${GLOBALS.DATA_BRACKETS_ID_ATTR}]`);
20842137
allElements.forEach(el => el.setAttribute("draggable", "false"));
2085-
this.element.setAttribute("draggable", "true");
20862138

2087-
this.element.addEventListener("dragstart", (event) => {
2088-
event.stopPropagation();
2089-
event.dataTransfer.setData("text/plain", this.element.getAttribute(GLOBALS.DATA_BRACKETS_ID_ATTR));
2090-
_dragStartChores(this.element);
2091-
_clearDropMarkers();
2092-
window._currentDraggedElement = this.element;
2093-
dismissUIAndCleanupState();
2094-
dismissImageRibbonGallery();
2095-
// Add drag image styling
2096-
event.dataTransfer.effectAllowed = "move";
2097-
});
2098-
2099-
this.element.addEventListener("dragend", (event) => {
2100-
event.preventDefault();
2101-
event.stopPropagation();
2102-
_dragEndChores(this.element);
2103-
_clearDropMarkers();
2104-
_stopAutoScroll();
2105-
delete window._currentDraggedElement;
2106-
});
2139+
// we handle the svg elements differently as draggable attribute doesn't work on SVG namespace
2140+
// so for svgs we add mouse related listeners and internally we call the drag related functions
2141+
if (this.element && this.element.namespaceURI === "http://www.w3.org/2000/svg") {
2142+
this.element.addEventListener("mousedown", (event) => { onDragMouseDown(event, this.element); });
2143+
} else { // for normal elements
2144+
this.element.setAttribute("draggable", "true");
2145+
this.element.addEventListener("dragstart", (event) => { onDragStart(event, this.element); });
2146+
this.element.addEventListener("dragend", (event) => { onDragEnd(event, this.element); });
2147+
}
21072148
},
21082149

21092150
_style: function() {
@@ -5805,6 +5846,8 @@ function RemoteFunctions(config = {}) {
58055846
window.document.removeEventListener("drop", onDrop);
58065847
window.document.removeEventListener("dragleave", onDragLeave);
58075848
window.document.removeEventListener("keydown", onKeyDown);
5849+
window.document.removeEventListener("mousemove", onDragMouseMove);
5850+
window.document.removeEventListener("mouseup", onDragMouseUp);
58085851
unregisterInteractionBlocker();
58095852

58105853
if (config.mode === 'edit') {
@@ -5821,6 +5864,8 @@ function RemoteFunctions(config = {}) {
58215864
window.document.addEventListener("drop", onDrop);
58225865
window.document.addEventListener("dragleave", onDragLeave);
58235866
window.document.addEventListener("keydown", onKeyDown);
5867+
window.document.addEventListener("mousemove", onDragMouseMove);
5868+
window.document.addEventListener("mouseup", onDragMouseUp);
58245869

58255870
// this is to block all the interactions of the user created elements
58265871
// so that lets say user created link doesn't redirect in edit mode

0 commit comments

Comments
 (0)