Drag and Drop

← Events and Gestures
STRVCT

Browser drag-and-drop support for views and nodes, covering drop targets, drag sources, and MIME-type dispatch.

Overview

The browser's native HTML5 drag-and-drop API is low-level and inconsistent—you must manually parse DataTransfer objects, handle files versus text strings differently, prevent default browser navigation on dropped files, and manage empty-space drops that bypass child elements.

STRVCT wraps this into a clean, declarative protocol:

  • Drop Targets: Views register to accept dropped content (setIsRegisteredForBrowserDrop(true)). Dropped data arrives pre-parsed, typed by MIME, and dispatched directly to a handler method named by convention.
  • Drag Sources: Views register as draggable sources (setIsRegisteredForBrowserDrag(true)), populating DataTransfer payloads when a drag initiates.
1. Browser DOM Drop Event DataTransfer with files, text, HTML, or JSON 2. SvDropListener Target Check dragenter / dragover / dragleave / drop; Checks view.acceptsDrop(event) 3. MIME-Type Convention Dispatch text/plain → onBrowserDropTextPlain(dataChunk) text/html → onBrowserDropTextHtml(dataChunk) image/png → onBrowserDropImagePng(dataChunk) app/json → onBrowserDropApplicationJson(chunk) 4. View or Model Node Handler Runs Application processes typed data chunk; unhandled MIME types are silently ignored Register drop support via setIsRegisteredForBrowserDrop(true) and implement one handler method per accepted MIME type.

Key Framework Classes

File / Class NamePurpose & Responsibilities
SvDomView_browserDragAndDrop.jsCategory on SvDomView implementing drop/drag target APIs.
SvDropListener.jsManages element drop event listeners (dragenter, dragover, dragleave, drop).
SvDragListener.jsManages element drag source event listeners (dragstart, dragend).
SvDocumentBody.jsGlobal drop prevention on document.body to stop browser file navigation.

Drop Targets API

1. Registering a View for Drops

init () {
    super.init();
    this.setIsRegisteredForBrowserDrop(true); // Attaches SvDropListener
    return this;
}

2. Accepting or Rejecting Drops

Override acceptsDrop(event) to inspect incoming transfer types:

acceptsDrop (event) {
    // Inspect event.dataTransfer.types
    return event.dataTransfer.types.includes("text/plain");
}

3. MIME Type Method Dispatch (dropMethodForMimeType)

MIME TypeConvention Handler Method Name
text/plainonBrowserDropTextPlain(dataChunk)
text/htmlonBrowserDropTextHtml(dataChunk)
image/pngonBrowserDropImagePng(dataChunk)
image/jpegonBrowserDropImageJpeg(dataChunk)
application/jsononBrowserDropApplicationJson(dataChunk)

4. Data Chunk Object (SvDataUrl)

Dropped payloads are wrapped in an SvDataUrl instance (dataChunk):

  • dataChunk.mimeType(): Returns the MIME type string.
  • dataChunk.decodedData(): Returns the decoded string or JSON content.
  • dataChunk.setDataUrlString(url): Contains the data URL string for dropped files.

5. Visual Drag Highlighting

Override styling hooks for hover feedback:

dragHighlight () {
    this.setBorder("2px dashed cornflowerblue");
}

dragUnhighlight () {
    this.setBorder("none");
}

Drag Sources API

To make a view draggable:

init () {
    super.init();
    this.setIsRegisteredForBrowserDrag(true);
    return this;
}

// Populate transfer payload on drag start
onBrowserDragStart (event) {
    const dt = event.dataTransfer;
    dt.setData("text/plain", this.node().title());
    dt.setData("application/json", JSON.stringify(this.node().asJson()));
}