Drag and Drop Plugin
Handles drag and drop operations for images, content fragments, and FileBrowser items within the editor.
Description
This plugin enables drag and drop functionality for:
- Moving images within the editor
- Copying images from FileBrowser
- Dragging selected content (text, HTML) to a new position
- Moving vs copying modes (Ctrl key toggles copy mode)
- Dropping external HTML/plain text content
Note: There's a TODO comment in the code suggesting this plugin should eventually replace drag-and-drop-element plugin for complete custom moving functionality.
Features
- Image Dragging: Drag images within editor or from FileBrowser
- Content Fragment Dragging: Move selected HTML content
- Copy Mode: Hold Ctrl/Cmd to copy instead of move
- Cursor Tracking: Cursor updates in real-time during drag
- External Content: Drop HTML/text from outside editor
- Range Preservation: Maintains selection range during drag
- Auto-insert: Automatically inserts content at drop position
- Event Integration: Fires
pasteandafterInsertImageevents
Move Mode (Default for editor content)
- Drag content from editor without Ctrl key
- Original content is removed (extracted)
- Content appears at new position
Copy Mode
- Hold Ctrl/Cmd while dragging editor content
- External content (FileBrowser, outside editor) always copies
- Original content remains in place
- Duplicate appears at drop position
Basic Image Drag
const editor = Jodit.make('#editor');
editor.value = '<p>Text</p><img src="image.jpg" />';
// User can drag the image to reposition it within editor
// Without Ctrl: image moves
// With Ctrl: image is copied
Drag from FileBrowser
const editor = Jodit.make('#editor', {
filebrowser: {
ajax: {
url: '/api/filebrowser'
}
}
});
// User opens FileBrowser, drags an image item into editor
// Image is automatically inserted as <img> or <a> tag
Listen to Drop Events
const editor = Jodit.make('#editor');
editor.e.on('afterInsertImage', (image) => {
console.log('Image inserted via drag-drop:', image.src);
});
editor.e.on('paste', (event) => {
console.log('External content dropped:', event);
});
Disable Plugin
const editor = Jodit.make('#editor', {
disablePlugins: ['dragAndDrop']
// Falls back to browser default drag-drop
});
Drag Start (onDragStart)
- Listens to
dragstarton window, document, and editor - Removes any old draggable element
- Checks if drag source is inside editor (
isFragmentFromEditor) - Determines mode:
- Editor content: Move mode (or Copy if Ctrl pressed)
- External content: Always Copy mode
- If editor content, stores current range in
bufferRange - Records starting mouse position (
startDragPoint) - If dragging FileBrowser item or
<img>, clones it todraggable - Attaches drag event listeners
Drag Over (onDrag)
- Fires every ~10ms (throttled to
defaultTimeout / 10) - If
draggableexists, hides popups - Updates cursor position to follow mouse:
insertCursorAtPoint() - Prevents default browser behavior
Drop (onDrop)
-
Checks if dropping files (handled elsewhere if true)
-
If no files:
- External drop (no
isFragmentFromEditorand nodraggable): firespasteevent - Gets work fragment via
__getWorkFragment() - Removes all current selections
- Inserts cursor at drop point
- Inserts fragment at new position
- Prevents default behavior
- External drop (no
-
Cleans up: removes listeners, resets flags
Get Work Fragment (__getWorkFragment)
Determines what to insert based on drag source:
Case 1: No draggable, has range (selected content)
- Copy mode:
range.cloneContents()- duplicates content - Move mode:
range.extractContents()- removes and returns content
Case 2: Draggable image
- Copy mode:
- Check if file: create
<a href="...">link - Otherwise: create
<img src="...">image
- Check if file: create
- Move mode: Return original element reference
Case 3: External HTML/text
- Extract from
dataTransfer(HTML or plain text) - Create fragment from HTML string
Insert Fragment (__insertFragment)
- Inserts node at cursor position
- If fragment has children, selects the inserted range
- Fires
synchroevent - If image, fires
afterInsertImageevent
Drag End (onDragEnd)
- Removes temporary
draggableelement - Resets
isCopyModeto false - Removes all drag event listeners
afterInsertImage
Fired when an image is inserted via drag-drop.
editor.e.on('afterInsertImage', (img) => {
console.log('Image inserted:', img);
});
paste
Fired when external content is dropped (not from editor).
editor.e.on('paste', (event) => {
console.log('External content dropped');
});
synchro
Fired after content insertion to sync editor state.
FileBrowser Integration
The plugin detects FileBrowser items:
// Checks if target has class 'jodit-filebrowser-files__item'
isFileBrowserFilesItem(target)
When dragging from FileBrowser:
- Extracts
<img>from item - Uses
data-srcorsrcattribute - Creates
<a>for files (whendata-is-file="1") - Creates
<img>for images
Configuration
This plugin has no configuration options. To disable:
const editor = Jodit.make('#editor', {
disablePlugins: ['dragAndDrop']
});
Notes
- Uses
@throttledecorator foronDrag(optimized to ~10ms intervals) - Uses
@autobinddecorator for event handlers - Stores original range in
bufferRangeduring drag - External content always uses copy mode
- Editor content defaults to move mode (Ctrl enables copy)
- Integrates with FileBrowser plugin
- Fires
hidePopupduring drag to dismiss open menus - Cleans up all event listeners in
beforeDestruct() - TODO: Future plan to replace
drag-and-drop-elementplugin