Search Plugin
- Features
- useSearch
- search.lazyIdleTimeout
- search.useCustomHighlightAPI
- search.fuzzySearch
- find Control
- Basic Usage
- Disable Search
- Programmatic Search
- Find Next/Previous
- Open Search Dialog
- Custom Fuzzy Search
- Listen to Search Events
- Performance Tuning
- Search Dialog
- Search Process
- LazyWalker
- Match Finding
- Highlighting Methods
- Replace Operation
- Caching
- Navigation
- openSearchDialog
- openReplaceDialog
- search
- searchNext
- searchPrevious
- afterFindAndSelect
- afterFindAndReplace
- Edge Cases
- Notes
- Typical Use Case
- Classes
- Interfaces
Provides find and replace functionality with a visual dialog interface. This plugin allows users to search for text in the editor, navigate between matches, and replace occurrences.
Features
- Visual search dialog with input fields
- Find text with highlighting
- Find next/previous navigation
- Replace functionality
- Match counter display
- Custom fuzzy search algorithm support
- LazyWalker for performance
- CSS Custom Highlight API support
- Auto-scrolling to matches
- Keyboard shortcuts
- Toolbar button with dropdown
- Search results caching
- Event-driven architecture
useSearch
Type: boolean
Default: true
Enables or disables the search plugin entirely.
Example:
const editor = Jodit.make('#editor', {
useSearch: false
});
search.lazyIdleTimeout
Type: number
Default: 0
(milliseconds)
Timeout for LazyWalker idle state during search. Higher values improve performance for large documents by spreading search work across frames.
Example:
const editor = Jodit.make('#editor', {
search: {
lazyIdleTimeout: 100 // 100ms idle timeout
}
});
search.useCustomHighlightAPI
Type: boolean
Default: true
if browser supports CSS.highlights
, otherwise false
Uses browser's native CSS Custom Highlight API for highlighting matches instead of wrapping text in spans.
Example:
const editor = Jodit.make('#editor', {
search: {
useCustomHighlightAPI: true
}
});
search.fuzzySearch
Type: FuzzySearch
Default: undefined
(uses built-in fuzzy search)
Custom function to search for strings within text. Must implement the FuzzySearch
interface: (needle: string, haystack: string, offset: number) => [index: number, length: number]
.
Example:
const editor = Jodit.make('#editor', {
search: {
fuzzySearch: (needle, haystack, offset) => {
// Case-insensitive search
const index = haystack.toLowerCase().indexOf(needle.toLowerCase(), offset);
return [index, needle.length];
}
}
});
find
Control
Icon: 'search'
Tooltip: 'Find'
Group: 'search'
Dropdown List:
search
: "Find" - Opens search dialogfindNext
: "Find Next" - Finds next matchfindPrevious
: "Find Previous" - Finds previous matchreplace
: "Replace" - Opens replace dialog
Opens search/replace dialog or navigates through matches.
Basic Usage
const editor = Jodit.make('#editor');
// Click Find button in toolbar
// Enter search query
// Use navigation buttons
Disable Search
const editor = Jodit.make('#editor', {
useSearch: false
});
// or
const editor2 = Jodit.make('#editor2', {
disablePlugins: ['search']
});
Programmatic Search
const editor = Jodit.make('#editor');
editor.value = '<p>this text contains some text</p>';
// Find and select first match
editor.e.fire('search', 'some text').then(() => {
console.log('Selected!');
});
Find Next/Previous
const editor = Jodit.make('#editor');
editor.value = '<p>this text contains some text and some text</p>';
// Find first match
editor.e.fire('search', 'some text').then(() => {
console.log('First match selected');
// Find next match
editor.e.fire('searchNext', 'some text').then(() => {
console.log('Second match selected');
});
});
Open Search Dialog
const editor = Jodit.make('#editor');
// Open search dialog
editor.execCommand('openSearchDialog');
// Open replace dialog
editor.execCommand('openReplaceDialog');
Custom Fuzzy Search
const editor = Jodit.make('#editor', {
search: {
fuzzySearch: (needle, haystack, offset) => {
// Exact match only
const index = haystack.indexOf(needle, offset);
return [index, needle.length];
}
}
});
Listen to Search Events
const editor = Jodit.make('#editor');
editor.e.on('afterFindAndSelect', () => {
console.log('Match selected');
});
editor.e.on('afterFindAndReplace', () => {
console.log('Text replaced');
});
Performance Tuning
const editor = Jodit.make('#editor', {
search: {
lazyIdleTimeout: 200 // Spread search across frames
}
});
Search Dialog
The plugin provides a UI with:
- Search input field
- Replace input field (in replace mode)
- Find Next button
- Find Previous button
- Replace button
- Match counter (e.g., "1 of 5")
Search Process
- Input Query: User types in search field
- Find Matches: Plugin walks DOM tree to find all occurrences
- Highlight: Wraps matches in spans or uses Highlight API
- Cache Results: Stores found ranges for reuse
- Navigate: User clicks next/previous to cycle through matches
- Select: Current match is selected in editor
- Scroll: Editor scrolls to make selected match visible
LazyWalker
For performance, search uses LazyWalker
:
- Processes DOM nodes incrementally
- Yields to browser between chunks
- Prevents UI freezing on large documents
- Respects
lazyIdleTimeout
for frame splitting
Match Finding
The SentenceFinder
class:
- Collects text nodes from editor
- Builds continuous text content
- Applies fuzzy search algorithm
- Returns array of
ISelectionRange
for matches
Highlighting Methods
CSS Custom Highlight API (useCustomHighlightAPI: true
):
- Uses browser's native
CSS.highlights
- No DOM modification
- Better performance
- Limited browser support
Span Wrapping (useCustomHighlightAPI: false
):
- Wraps matches in
<span>
withjd-tmp-selection
attribute - Works in all browsers
- Cleaned up via
clearSelectionWrappers()
- Removed from HTML output via
afterGetValueFromEditor
event
Replace Operation
When replacing:
- Find Match: Locates current match in ranges
- Delete Content: Removes match text from range
- Insert Replacement: Inserts new text node
- Clear Highlights: Removes all highlight wrappers
- Set Cursor: Positions cursor after replacement
- Re-search: Finds matches again with updated content
- Sync: Updates editor value
Caching
Search results cached by query string:
- Key: search query
- Value: Promise<ISelectionRange[]>
- Invalidated on editor change
- Validation checks node connectivity
Navigation
Find Next:
- Increments current index
- Wraps to 0 at end
- Selects range at new index
- Scrolls into view
Find Previous:
- Decrements current index
- Wraps to last at beginning
- Selects range at new index
- Scrolls into view
openSearchDialog
Opens the search dialog.
Syntax:
editor.execCommand('openSearchDialog')
Example:
editor.execCommand('openSearchDialog');
openReplaceDialog
Opens the replace dialog (search dialog with replace field).
Syntax:
editor.execCommand('openReplaceDialog')
Example:
editor.execCommand('openReplaceDialog');
search
Fired to find and select first match of query.
Parameters:
query
(string): Text to search for
Returns: Promise
Example:
editor.e.fire('search', 'hello').then((found) => {
console.log(found ? 'Found' : 'Not found');
});
searchNext
Fired to find and select next match.
Parameters:
query
(string, optional): Text to search for
Example:
editor.e.fire('searchNext', 'hello');
searchPrevious
Fired to find and select previous match.
Parameters:
query
(string, optional): Text to search for
Example:
editor.e.fire('searchPrevious', 'hello');
afterFindAndSelect
Fired after a match is selected.
Example:
editor.e.on('afterFindAndSelect', () => {
console.log('Match selected');
});
afterFindAndReplace
Fired after text is replaced.
Example:
editor.e.on('afterFindAndReplace', () => {
console.log('Text replaced');
});
Edge Cases
-
Empty Query: Returns empty results array
-
No Matches: Dialog shows "0 of 0"
-
Query Change: Clears highlights and re-searches
-
Editor Change: Invalidates cache
-
Mode Switch: Closes dialog on mode change
-
Dialog Close: Clears highlights and resets counters
-
Node Disconnection: Cache validation checks node connectivity
-
Click in Editor: Resets current index
-
Large Documents: LazyWalker prevents UI freezing
-
Selection State: Saved/restored during operations
Notes
- Plugin is class-based, extends
Plugin
base class - Uses
@watch
,@autobind
,@cache
,@cached
decorators - Search button in 'search' toolbar group
- Custom UI class
UISearch
for dialog - Event namespacing
.search
for clean removal - Cache stored as IDictionary keyed by query
- LazyWalker instances:
walker
(main),walkerCount
(counting) - The
SentenceFinder
class handles text node traversal - Highlight wrappers have
jd-tmp-selection
attribute - CSS Custom Highlight API check:
typeof globalWindow.Highlight !== 'undefined'
- Cleanup via
clearSelectionWrappers()
andclearSelectionWrappersFromHTML()
- Drawing highlights uses
requestAnimationFrame
for performance - Batch size: 5 ranges per frame
- The
highlightTextRanges()
helper creates highlight spans - Current index is 1-based for display (0-based internally)
- The plugin properly cleans up event listeners on destruction
- Replace updates cursor position after insertion
- Scroll uses
scrollIntoViewIfNeeded()
helper - Find operations return Promises for async completion
- The
findCurrentIndexInRanges()
method matches current selection - Cache invalidation on change event
- Debounced counter updates on keydown/mousedown
- Selection info stored in
ui.selInfo
- The
tryScrollToElement()
method handles scroll for matches - Counter updates triggered via
ui:needUpdateCounters
event - Replace triggered via
ui:pressReplaceButton
event - The
wrapFrameRequest
tracks animation frame ID - Previous query tracked to detect query changes
- Draw promise allows waiting for highlight completion
Typical Use Case
Users need to locate specific text in documents and optionally replace it. The search plugin provides this by:
- Providing visual search dialog
- Highlighting all matches in editor
- Showing match count (e.g., "3 of 15")
- Allowing navigation between matches
- Supporting find and replace operations
This improves user experience by:
- Making text easy to locate visually
- Supporting keyboard-driven workflow
- Handling large documents efficiently
- Providing familiar find/replace interface
- Auto-scrolling to matches
Classes
Interfaces
clearNativeSelection
clearNativeSelection(jodit
): void
Parameters
Name | Type |
---|---|
jodit |
IJodit |
Returns
void
Defined in
jodit/src/plugins/search/helpers/highlight-text-ranges.ts:147