attachDrag()

in ui/src/main/frontend/js/editor.js [162:302]


      attachDrag(ed) {
        let dragImage;
        let dragActive = false;
        function handleOver(evt) {
          evt.preventDefault();
          document.querySelectorAll(".sling-cms-droptarget").forEach((dt) => {
            dt.classList.remove("sling-cms-droptarget__is-over");
          });
          evt.target.classList.add("sling-cms-droptarget__is-over");
        }
        function handleLeave(evt) {
          evt.target.classList.remove("sling-cms-droptarget__is-over");
        }
        function handleDrop(evt) {
          evt.preventDefault();

          const sourcePath = evt.dataTransfer.getData("path");
          const sourceName = evt.dataTransfer.getData("name");
          const targetPath = `${evt.target.dataset.path}/${sourceName}`;

          async function move() {
            const formData = new FormData();
            formData.append("_charset_", "utf-8");
            if (sourcePath !== targetPath) {
              formData.append(":dest", targetPath);
              formData.append(":operation", "move");
            }
            formData.append(":nameHint", sourceName);
            formData.append(":order", evt.target.dataset.order);
            let ui;
            if (typeof Sling !== "undefined") {
              ui = Sling.CMS.ui;
            } else {
              ui = window.parent.Sling.CMS.ui;
            }
            const response = await fetch(sourcePath, {
              method: "POST",
              body: formData,
              cache: "no-cache",
              headers: {
                Accept: "application/json",
              },
            });
            const res = await response.json();
            if (!response.ok) {
              ui.confirmMessage(
                "Failed to move",
                res["status.message"] || response.statusText,
                () => {}
              );
            } else {
              ui.confirmReload(res, "success");
            }
            evt.target.classList.remove("sling-cms-droptarget__is-over");
          }
          if (evt.target.dataset.create) {
            const formData = new FormData();
            formData.append("_charset_", "utf-8");
            formData.append("jcr:primaryType", "nt:unstructured");
            let ui;
            if (typeof Sling !== "undefined") {
              ui = Sling.CMS.ui;
            } else {
              ui = window.parent.Sling.CMS.ui;
            }
            fetch(evt.target.dataset.path, {
              method: "POST",
              body: formData,
              cache: "no-cache",
              headers: {
                Accept: "application/json",
              },
            })
              .then((response) => {
                if (!response.ok) {
                  throw new Error(response.statusText);
                }
                return response.json();
              })
              .catch((error) => {
                ui.confirmMessage(error.message, error.message, () => {});
              })
              .then(() => {
                move();
              });
          } else {
            move();
          }
        }
        function activateTargets() {
          if (dragActive) {
            document.querySelectorAll(".sling-cms-droptarget").forEach((dt) => {
              dt.classList.add("sling-cms-droptarget__is-active");
              dt.addEventListener("dragover", handleOver);
              dt.addEventListener("dragleave", handleLeave);
              dt.addEventListener("drop", handleDrop);
            });
          }
        }
        function deactivateTargets() {
          dragActive = false;
          document.querySelectorAll(".sling-cms-droptarget").forEach((dt) => {
            dt.classList.remove("sling-cms-droptarget__is-active");
            dt.removeEventListener("dragover", handleOver);
            dt.removeEventListener("dragleave", handleLeave);
            dt.removeEventListener("drop", handleDrop);
          });
          if (dragImage) {
            dragImage.remove();
          }
        }
        ed.addEventListener("dragstart", (evt) => {
          const event = evt;
          event.stopPropagation();
          dragActive = true;
          event.dataTransfer.effectAllowed = "move";
          dragImage = document.createElement("div");
          dragImage.setAttribute(
            "style",
            `position: absolute; left: 0px; top: 0px; width: ${ed.offsetWidth}px; height: ${ed.offsetHeight}px; padding: 0.5em; background: grey; z-index: -1`
          );
          dragImage.innerText = ed.querySelector(".level-right").innerText;
          document.body.appendChild(dragImage);
          event.dataTransfer.setDragImage(dragImage, 20, 20);
          event.dataTransfer.setData(
            "path",
            ed.closest(".sling-cms-component").dataset.slingCmsResourcePath
          );
          const resourceType = ed.closest(".sling-cms-component").dataset
            .slingCmsResourceType;
          event.dataTransfer.setData(
            "name",
            resourceType.substr(resourceType.lastIndexOf("/") + 1) +
              "_" +
              Math.random().toString(36).substring(2)
          );

          setTimeout(activateTargets, 10);
        });
        ed.addEventListener("dragend", deactivateTargets);
      },