Jodit WYSIWYG Editor
repository·main·Indexed 23 days ago
https://github.com/xdan/joditA pure-TypeScript WYSIWYG editor featuring a built-in file browser and image editor. Jodit is highly extensible via a plugin system and supports deployment through ESM, UMD, and CDN. Version 4.13.10 includes a component system for lifecycle management, an Async module for safe asynchronous operations, and a Create module for context-aware DOM creation in iframe or window modes.
What's inside jodit
- Jodit provides a collection of reusable UI widgets designed for building editor components. These widgets can be used to create popups, dialogs, and various editor controls such as tabs and pickers.
Overview of the File Browser Module
mainThe File Browser module allows users to manage remote files and images directly within the Jodit editor. It supports uploading, deleting, renaming, and moving files through a configurable server backend.
Important Prerequisite: This module requires a server-side implementation to function. It will not work without a backend that supports the required API. Jodit provides a reference implementation in PHP called
jodit-connectors.Overview of the Clean HTML Plugin
mainThe Clean HTML Plugin automatically sanitizes HTML content within the Jodit editor to prevent XSS attacks and normalize markup. It continuously monitors changes (on change, paste, or mode switch) to remove dangerous scripts, filter tags and attributes, and enforce CSS property restrictions. It also provides an "Eraser" button in thefont-stylegroup to clear formatting from selected text.Use the Debug Plugin features
mainOnce enabled, the Debug Plugin adds a panel to the editor workplace with three main sections:
- DOM Tree (
.jodit-debug__tree): A live hierarchical view of the editor content. It highlights selected nodes, shows cursor positions with a|marker, and marks empty text nodes in red or invisible spaces asINV. - Selection Info (
.jodit-debug__sel): Displays the current range state, showing thestartContainer(node name and offset) andendContainer(node name and offset). - Event Log (
.jodit-debug__events): A real-time, auto-scrolling stream of over 40 editor and browser events (e.g.,keydown,beforeCommand,paste) including timestamps and event details like keyboard modifiers.
- DOM Tree (
The Toolbar Module overview
mainThe Toolbar module is responsible for providing the editor's main user interface toolbar. It acts as a host for various button collections and formatting controls used to manipulate content within the Jodit editor.Use the Justify Plugin for text alignment
mainThe Justify Plugin provides text alignment functionality for the Jodit editor, allowing users to align text left, center, right, or justify within block elements using thetext-alignCSS property. It includes a dropdown button that dynamically updates its icon or text based on the current alignment and automatically wraps inline content in block elements when necessary.Overview of the Jodit plugin system
mainJodit's functionality is extended through a plugin system. Plugins are written in TypeScript and compiled to JavaScript. They can be loaded dynamically by the application to extend the editor's capabilities.What is the View UI component?
mainTheViewcomponent is a base UI class used to create standalone components that do not require aJoditeditor instance. It provides its own internal event system (events) and anAsyncmodule. While most Jodit components require a parentIJoditorIViewBasedinstance,Viewallows for the creation of independent UI elements likeDialog.How the Stat Plugin calculates counts
mainThe plugin uses a throttled calculation method (
calc) to ensure performance during rapid typing. Calculations are triggered bychange,keyup,afterInit,changePlace, andafterAddPlaceevents.Character Counting Logic
- If
countHTMLCharsistrue: Counts all characters injodit.value(full HTML). - If
countHTMLCharsisfalse: Usesjodit.text(visible text).- If
countTextSpacesistrue: Removes invisible/zero-width spaces and line breaks (\r\n), then counts the rest. - If
countTextSpacesisfalse: Removes all spaces viaSPACE_REG_EXPbefore counting.
- If
Word Counting Logic
- Always uses
jodit.text(visible text only). - Removes invisible spaces.
- Splits text by
SPACE_REG_EXP(whitespace regex). - Filters out empty strings and returns the resulting array length.
- If
How the Tab plugin handles list nesting
mainThe Tab plugin provides word-processor-like behavior for hierarchical lists. It intercepts
keydownevents for the Tab key andbeforeCommandevents forindent/outdentcommands.Indentation (Tab)
When a user presses
Tabinside an<li>:- The plugin identifies the closest
<li>ancestor. - It checks if a previous sibling exists (indentation is not possible for the first item).
- It either moves the current
<li>into an existing nested list or creates a new nested list (<ul>or<ol>) that clones the parent list's tag and attributes, then appends the current<li>to it.
Outdentation (Shift+Tab)
When a user presses
Shift+Tabinside an<li>:- The plugin identifies the parent
<li>containing the current nested list. - It moves the current
<li>to be a sibling of the parent<li>(outdenting). - If the item is the first or only item in the sublist, the entire nested list structure is removed.
- If there are subsequent items in the sublist, the plugin clones the list structure to ensure remaining items stay grouped.
Cursor Preservation
To prevent the cursor from jumping during DOM manipulation, the plugin uses "fake cursor markers" (created via
jodit.createInside.fake()). It inserts these markers at the selection start/end, performs the DOM restructuring, and then restores the cursor position by recreating the range between the markers.- The plugin identifies the closest
How Data URI to Blob conversion works
mainTo optimize performance, the Image Processor plugin can convert base64 data URIs into temporary Blob URLs for the editor view. This prevents the browser from struggling to render massive base64 strings directly in the DOM.
Key Behaviors
- In Editor View: Images use
blob:URLs (e.g.,blob:http://localhost:2000/...). - In Source/Value: Images retain their original
data:URIs. When you calleditor.value, the plugin automatically restores the original base64 strings. - Transparency: The conversion is handled internally. You can retrieve the original data via
editor.valueoreditor.getElementValue(), buteditor.getNativeEditorValue()will show theblob:URLs used in the DOM.
Example: Verifying Value Formats
const editor = Jodit.make('#editor', { imageProcessor: { replaceDataURIToBlobIdInView: true } }); // Set content with base64 image editor.value = '<p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII="/></p>'; // Get value - returns original data URI console.log(editor.value); // Output: <p><img src="data:image/png;base64,iVBORw0KG..."/></p> // Get native editor value - shows blob URL console.log(editor.getNativeEditorValue()); // Output: <p><img src="blob:http://localhost:2000/..."/></p> // Get element value - returns original data URI console.log(editor.getElementValue()); // Output: <p><img src="data:image/png;base64,iVBORw0KG..."/></p>- In Editor View: Images use
How the Sticky Plugin works
mainThe Sticky Plugin manages the toolbar's position based on the window's scroll position and the editor's location in the document.
Core Logic
- Activation: The toolbar becomes sticky when the user scrolls past the top of the editor container. It remains sticky until the user scrolls past the bottom of the editor.
- Modes: The plugin only operates in WYSIWYG mode. It is automatically disabled when the editor is in Source mode.
- Mobile Detection: Mobile behavior is determined by comparing the container width to the
sizeSMconfiguration option (defaulting to 768px). IftoolbarDisableStickyForMobileistrue, the plugin will not activate on narrow viewports. - Layout Stability: To prevent content jumping when the toolbar switches to
position: fixed, the plugin (specifically in older IE versions) manages a dummy box to preserve the layout space. - Width Management: The plugin automatically recalculates the toolbar width on resize and sticky state changes to ensure it matches the container width (accounting for a 2px border).