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
paste
andafterInsertImage
events
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
});
onDragStart
)
Drag Start (- Listens to
dragstart
on 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
onDrag
)
Drag Over (- Fires every ~10ms (throttled to
defaultTimeout / 10
) - If
draggable
exists, hides popups - Updates cursor position to follow mouse:
insertCursorAtPoint()
- Prevents default browser behavior
onDrop
)
Drop (-
Checks if dropping files (handled elsewhere if true)
-
If no files:
- External drop (no
isFragmentFromEditor
and nodraggable
): firespaste
event - 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
__getWorkFragment
)
Get Work Fragment (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
__insertFragment
)
Insert Fragment (- Inserts node at cursor position
- If fragment has children, selects the inserted range
- Fires
synchro
event - If image, fires
afterInsertImage
event
onDragEnd
)
Drag End (- Removes temporary
draggable
element - Resets
isCopyMode
to 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-src
orsrc
attribute - 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
@throttle
decorator foronDrag
(optimized to ~10ms intervals) - Uses
@autobind
decorator for event handlers - Stores original range in
bufferRange
during drag - External content always uses copy mode
- Editor content defaults to move mode (Ctrl enables copy)
- Integrates with FileBrowser plugin
- Fires
hidePopup
during drag to dismiss open menus - Cleans up all event listeners in
beforeDestruct()
- TODO: Future plan to replace
drag-and-drop-element
plugin