Select Plugin
- Features
- select.normalizeSelectionBeforeCutAndCopy
- select.normalizeTripleClick
- Basic Element Click Events
- Mouse Events on Elements
- Editor Click Event
- Outside Click Detection
- Selection Normalization
- Custom Event Handling
- Disable Triple Click Normalization
- Event Proxying
- Event Name Format
- Selection Normalization Before Copy/Cut
- Triple Click Normalization
- Select All Command
- Outside Click Detection
- Before Cut Normalization
- click[NodeName], mousedown[NodeName], etc.
- clickEditor
- outsideClick
- selectall
- Edge Cases
- Notes
- Typical Use Case
- Classes
A utility plugin that normalizes selection behavior and provides event proxying for DOM element interactions. This plugin handles selection normalization for copy/cut operations, triple-click selection, and fires element-specific events for easier event handling.
Features
- Event proxying for DOM elements
- Element-specific event firing (e.g.,
clickImg
,mousedownTable
) - Selection normalization before copy/cut
- Triple-click selection normalization
- Select all command handling
- Outside click detection
- Event bubbling through DOM hierarchy
- Support for touch events
- Custom event naming with camelCase
select.normalizeSelectionBeforeCutAndCopy
Type: boolean
Default: false
When enabled, expands selection to cover entire selected containers before copy/cut operations when selection spans from beginning to end of inline content.
Behavior:
<ul><li>|test|</li></ul>
becomes|<ul><li>test</li></ul>|
<ul><li>|test|</li><li>test</li></ul>
becomes<ul>|<li>test</li><li>test</li>|</ul>
Example:
const editor = Jodit.make('#editor', {
select: {
normalizeSelectionBeforeCutAndCopy: true
}
});
select.normalizeTripleClick
Type: boolean
Default: true
Normalizes selection after triple-click to select entire block element instead of just text content.
Behavior:
- Triple-click selects the entire block element
<ul><li>|test</li><li>|pop</li></ul>
becomes<ul><li>|test|</li><li>pop</li></ul>
Example:
const editor = Jodit.make('#editor', {
select: {
normalizeTripleClick: true
}
});
Basic Element Click Events
const editor = Jodit.make('#editor');
// Listen for clicks on images
editor.e.on('clickImg', (img) => {
console.log('Image clicked:', img.src);
});
// Listen for clicks on tables
editor.e.on('clickTable', (table) => {
console.log('Table clicked');
});
// Listen for clicks on links
editor.e.on('clickA', (link) => {
console.log('Link clicked:', link.href);
});
Mouse Events on Elements
const editor = Jodit.make('#editor');
// Mousedown on paragraph
editor.e.on('mousedownP', (p, e) => {
console.log('Paragraph mousedown');
});
// Mouseup on div
editor.e.on('mouseupDiv', (div, e) => {
console.log('Div mouseup');
});
// Touch events
editor.e.on('touchstartSpan', (span, e) => {
console.log('Span touch start');
});
editor.e.on('touchendButton', (button, e) => {
console.log('Button touch end');
});
Editor Click Event
const editor = Jodit.make('#editor');
// Click directly on editor (not on child elements)
editor.e.on('clickEditor', (editor, e) => {
console.log('Clicked on editor root');
});
Outside Click Detection
const editor = Jodit.make('#editor');
editor.e.on('outsideClick', (e) => {
console.log('Clicked outside editor');
// Close popups, hide toolbars, etc.
});
Selection Normalization
const editor = Jodit.make('#editor', {
select: {
normalizeSelectionBeforeCutAndCopy: true,
normalizeTripleClick: true
}
});
// Copy/cut will expand selection to include containers
// Triple-click will select entire block
Custom Event Handling
const editor = Jodit.make('#editor');
// Event name format: eventType + NodeName (camelCase)
editor.e.on('mousedownTd', (td, e) => {
console.log('Table cell mousedown');
// Prevent default behavior
return false;
});
editor.e.on('clickLi', (li, e) => {
console.log('List item clicked');
e.stopPropagation();
});
Disable Triple Click Normalization
const editor = Jodit.make('#editor', {
select: {
normalizeTripleClick: false
}
});
// Triple-click uses browser default behavior
Event Proxying
The plugin listens to these events on the editor:
click
mousedown
touchstart
mouseup
touchend
For each event, it:
- Starts at event target
- Walks up DOM tree to editor root
- For each element, fires
eventType + nodeName
(camelCase) - Stops if handler returns non-undefined value
- If reaches editor root on click, fires
clickEditor
Event Name Format
Events follow camelCase pattern:
click
+img
→clickImg
mousedown
+table
→mousedownTable
touchstart
+a
→touchstartA
- Node names converted to lowercase then camelCased
Selection Normalization Before Copy/Cut
When normalizeSelectionBeforeCutAndCopy
is enabled:
- Check Conditions: Selection must not be collapsed and must be in editor
- Expand Selection: Calls
s.expandSelection()
- Effect: Selection expands to include parent blocks if content fully selected
Example transformation:
<!-- Before -->
<ul><li>|selected text|</li></ul>
<!-- After normalization -->
|<ul><li>selected text</li></ul>|
This ensures consistent copy/paste behavior when entire inline contents are selected.
Triple Click Normalization
When normalizeTripleClick
is enabled and user triple-clicks:
- Detect Triple Click:
e.detail === 3
- Check Position: Selection starts at offset 0 in text node
- Select Block: Selects closest block element or text node itself
- Result: Entire block selected instead of line
This provides more intuitive selection behavior matching user expectations.
Select All Command
The plugin intercepts selectall
command:
- Focus Editor: Ensures editor has focus
- Select Editor: Selects entire editor content
- Expand Selection: Normalizes selection boundaries
- Return False: Prevents default command execution
Outside Click Detection
The plugin fires outsideClick
event when:
- User clicks outside editor
- Click target is not inside editor
- Click target is not inside a Popup UI element
This allows other plugins to respond to focus loss.
Before Cut Normalization
Before cut command executes:
- Checks if selection is not collapsed
- Verifies selection is within editor
- Calls normalization if conditions met
click[NodeName]
, mousedown[NodeName]
, etc.
Fired when specific element type is clicked/interacted with. Node name is camelCased.
Parameters:
element
(HTMLElement): The clicked elementevent
(MouseEvent): Original mouse event
Example:
editor.e.on('clickImg', (img, e) => {
console.log('Image:', img);
console.log('Event:', e);
});
clickEditor
Fired when user clicks directly on editor root (not on child elements).
Parameters:
editor
(HTMLElement): The editor elementevent
(MouseEvent): Original click event
Example:
editor.e.on('clickEditor', (editor, e) => {
console.log('Clicked editor root');
});
outsideClick
Fired when user clicks outside the editor and popups.
Parameters:
event
(MouseEvent): Original mouse event
Example:
editor.e.on('outsideClick', (e) => {
console.log('Outside click detected');
});
selectall
Plugin intercepts this command to provide normalized select all behavior.
Example:
editor.execCommand('selectall');
// Selects entire editor content with expanded boundaries
Edge Cases
-
Event Bubbling Stop: Returning non-undefined from handler stops bubbling up DOM tree
-
Click on Editor:
clickEditor
only fires if click reaches editor root -
Outside Click Popups: Clicks in Popup elements don't trigger
outsideClick
-
Triple Click Detail: Relies on
e.detail === 3
for detection -
Normalization Conditions: Requires non-collapsed selection within editor
-
Touch Events: Supported alongside mouse events
-
Multiple Elements: Events fire for each element in bubble path
-
Return False: Can prevent default command behavior
Notes
- Plugin is class-based, extends
Plugin
base class - Uses
@autobind
and@watch
decorators - Event namespacing
.select
for clean removal - Proxy events list: click, mousedown, touchstart, mouseup, touchend
- Event names created via
camelCase()
helper - The
onStartSelection
method handles event proxying - Outside click uses
@watch('ow:click')
for window clicks - Triple click uses
@watch([':click'])
for editor clicks - Copy/cut normalization uses
@watch([':copy', ':cut'])
decorators - Select all uses
@watch([':beforeCommandSelectall'])
decorator - Before cut uses
@watch([':beforeCommandCut'])
decorator - The
expandSelection()
method expands to full element boundaries - Popup detection uses
UIElement.closestElement()
method - Node name converted to lowercase for event naming
- The plugin properly cleans up event listeners on destruction
- DOM traversal uses
target.parentElement
for bubbling - Click event special case for editor root
- Event result checked for
undefined
to continue bubbling - Outside click requires target not in editor or popup
- Selection normalization checks
isTrusted
andisOrContains
- Triple click checks
startOffset === 0
andDom.isText
- Select all calls
s.select(editor, true)
for inclusive selection - The
beforeCommandSelectAll
returnsfalse
to prevent default
Typical Use Case
Developers need easier event handling for specific element types and consistent selection behavior. The select plugin provides this by:
- Proxying DOM events to element-specific events
- Normalizing selection for copy/cut operations
- Handling triple-click selection properly
- Providing outside click detection
- Intercepting select all command
This improves developer experience by:
- Simplifying event listener code
- Avoiding manual DOM traversal
- Ensuring consistent selection behavior
- Supporting both mouse and touch events
- Providing semantic event names