msgProc: Drag & Drop

Drag-and-drop messages let your container receive dragged content from the operating system, other browser tabs, or other elements on the page. WakaPAC wraps the HTML5 Drag and Drop API into four messages that flow through msgProc like any other event, with coordinates packed into lParam and transfer data in event.detail.

Enabling Drop Targets

Add the data-pac-drop-target attribute to any element within or on a PAC container to accept drops. Without this attribute, drag events pass through to the browser's default behavior. The attribute value optionally sets the drop effect cursor — valid values are copy, move, and link. Defaults to copy if omitted or unrecognized.

<div data-pac-id="fileUploader" data-pac-drop-target>
    Drop files here
</div>

<!-- Explicit move cursor -->
<div data-pac-id="sortableList" data-pac-drop-target="move">
    Reorder items
</div>

The attribute can also be placed on a child element inside the container. The drop target attribute controls where drops are accepted; the nearest data-pac-id ancestor determines which container receives the messages.

<div data-pac-id="editor">
    <div class="toolbar">...</div>
    <div class="dropzone" data-pac-drop-target>
        Drop images here
    </div>
</div>

Message Flow

A complete drag-and-drop interaction produces this message sequence:

User drags item into container   → MSG_DRAGENTER  (once)
User hovers over a drop target   → MSG_DRAGOVER   (once per drop target element)
User drags item out of container → MSG_DRAGLEAVE  (once)

Or if the user drops:

User drags item into container   → MSG_DRAGENTER  (once)
User hovers over a drop target   → MSG_DRAGOVER   (once per drop target element)
User releases                    → MSG_DROP       (once)
Event cancellation: Drag-and-drop messages are not cancellable. Returning false from msgProc has no effect on default behavior — WakaPAC already prevents the browser's built-in drag handling (navigation on drop, rejection of drops on dragover) internally. Your msgProc only needs to handle the visual and data-processing logic.

Drag Enter (MSG_DRAGENTER)

MSG_DRAGENTER fires once when a drag operation first crosses the container boundary. Use this to show visual feedback such as highlighting the drop zone.

Message Parameters

Parameter Type Description
wParam number Modifier key and button state flags: MK_SHIFT, MK_CONTROL, MK_ALT, MK_RBUTTON, MK_MBUTTON
lParam number Packed cursor coordinates relative to the container. Extract using MAKEPOINTS()

Detail Properties

Property Type Description
types string[] Array of available data types in the drag operation (e.g., ['text/plain', 'Files']). Use this to determine what kind of content is being dragged before the drop occurs. See Common Type Values

Drag Over (MSG_DRAGOVER)

MSG_DRAGOVER fires once when the cursor enters a new drop target element within the container. It does not fire continuously — it dispatches when the underlying target element changes. Use this to update positional feedback such as insertion markers or placement previews.

Message Parameters

Parameter Type Description
wParam number Modifier key and button state flags: MK_SHIFT, MK_CONTROL, MK_ALT, MK_RBUTTON, MK_MBUTTON
lParam number Packed cursor coordinates relative to the container. Extract using MAKEPOINTS()

Detail Properties

Property Type Description
dropTarget HTMLElement The drop target element (the element with data-pac-drop-target) that the cursor is currently over
types string[] Array of available data types in the drag operation. See Common Type Values

Drag Leave (MSG_DRAGLEAVE)

MSG_DRAGLEAVE fires once when the drag operation exits the container boundary. Use this to remove visual feedback added during MSG_DRAGENTER.

Message Parameters

Parameter Type Description
wParam number Modifier key and button state flags: MK_SHIFT, MK_CONTROL, MK_ALT, MK_RBUTTON, MK_MBUTTON
lParam number Packed cursor coordinates relative to the container. Extract using MAKEPOINTS()

Detail Properties

Property Type Description
types string[] Array of available data types in the drag operation. See Common Type Values

Drop (MSG_DROP)

MSG_DROP fires when the user releases a dragged item over a drop target within the container. This is the only point where full drag data (text content, HTML, URIs, file contents) is accessible. The browser's default behavior (navigating to dropped files) is always prevented.

Message Parameters

Parameter Type Description
wParam number Modifier key and button state flags: MK_SHIFT, MK_CONTROL, MK_ALT, MK_RBUTTON, MK_MBUTTON
lParam number Packed cursor coordinates relative to the container. Extract using MAKEPOINTS()

Detail Properties

Property Type Description
dropTarget HTMLElement The drop target element (the element with data-pac-drop-target) that received the drop
text string Plain text content from the drag operation. Empty string if not available
html string HTML content from the drag operation. Empty string if not available
uri string URI list from the drag operation (e.g., dragged links). Empty string if not available
files object[] Array of file metadata objects, each containing name (string), size (number, bytes), and type (string, MIME type). Same shape as MSG_PASTE files. Empty array if no files
rawFiles FileList The native FileList from DataTransfer for direct file access. Use this for reading file contents or uploading

Example: File Upload Drop Zone

msgProc(event) {
    if (event.message === wakaPAC.MSG_DRAGENTER) {
        // Check if the drag contains files
        if (event.detail.types.includes('Files')) {
            this.dropHighlight = true;
        }
    }

    if (event.message === wakaPAC.MSG_DRAGLEAVE) {
        this.dropHighlight = false;
    }

    if (event.message === wakaPAC.MSG_DROP) {
        this.dropHighlight = false;

        // Process dropped files
        const files = event.detail.rawFiles;

        for (let i = 0; i < files.length; i++) {
            this.uploadFile(files[i]);
        }
    }
}

Common Type Values

The types array in MSG_DRAGENTER, MSG_DRAGOVER, and MSG_DRAGLEAVE identifies what kind of content is being dragged. Multiple values can be present at once — for example, dragging a link from a web page typically produces ['text/plain', 'text/html', 'text/uri-list'].

Value Source
'Files' Files dragged from the OS (file manager, desktop)
'text/plain' Plain text dragged from a text selection or input field
'text/html' Rich text dragged from a web page or editor
'text/uri-list' Links dragged from the browser address bar, bookmarks, or hyperlinks

Drag sources can also set custom MIME types, which appear in the array as-is.

Best Practices

  • Always provide visual feedback: Use MSG_DRAGENTER to highlight drop zones and MSG_DRAGLEAVE to remove the highlight. Users need to see where they can drop
  • Check types early: Use event.detail.types in MSG_DRAGENTER to determine if your container should accept the drag. Show different visual states for accepted vs rejected content
  • Use files for validation, rawFiles for processing: The files array provides lightweight metadata for type-checking and size validation. Use rawFiles only when you need to read actual file contents
  • Clean up on MSG_DRAGLEAVE: Any visual state added in MSG_DRAGENTER must be removed in MSG_DRAGLEAVE. The user may drag in and out multiple times before dropping
  • MSG_PASTE and MSG_DROP share a file shape: The files metadata array uses the same { name, size, type } structure in both messages. Code that validates file drops works for paste and vice versa