Jodit WYSIWYG Editor

repository·main·Indexed 23 days ago

https://github.com/xdan/jodit

A 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.

Tokens
116.3K
Snippets
371
Records
530
Agent score
84%

What's inside jodit

  1. Overview of the File Browser Module

    main

    The 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.

  2. Overview of the Clean HTML Plugin

    main
    The 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 the font-style group to clear formatting from selected text.
  3. Use the Debug Plugin features

    main

    Once enabled, the Debug Plugin adds a panel to the editor workplace with three main sections:

    1. 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 as INV.
    2. Selection Info (.jodit-debug__sel): Displays the current range state, showing the startContainer (node name and offset) and endContainer (node name and offset).
    3. 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.
  4. Use the Justify Plugin for text alignment

    main
    The Justify Plugin provides text alignment functionality for the Jodit editor, allowing users to align text left, center, right, or justify within block elements using the text-align CSS 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.
  5. Overview of the Jodit plugin system

    main
    Jodit'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.
  6. What is the View UI component?

    main
    The View component is a base UI class used to create standalone components that do not require a Jodit editor instance. It provides its own internal event system (events) and an Async module. While most Jodit components require a parent IJodit or IViewBased instance, View allows for the creation of independent UI elements like Dialog.
  7. How the Stat Plugin calculates counts

    main

    The plugin uses a throttled calculation method (calc) to ensure performance during rapid typing. Calculations are triggered by change, keyup, afterInit, changePlace, and afterAddPlace events.

    Character Counting Logic

    • If countHTMLChars is true: Counts all characters in jodit.value (full HTML).
    • If countHTMLChars is false: Uses jodit.text (visible text).
      • If countTextSpaces is true: Removes invisible/zero-width spaces and line breaks (\r\n), then counts the rest.
      • If countTextSpaces is false: Removes all spaces via SPACE_REG_EXP before counting.

    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.
  8. How the Tab plugin handles list nesting

    main

    The Tab plugin provides word-processor-like behavior for hierarchical lists. It intercepts keydown events for the Tab key and beforeCommand events for indent/outdent commands.

    Indentation (Tab)

    When a user presses Tab inside an <li>:

    1. The plugin identifies the closest <li> ancestor.
    2. It checks if a previous sibling exists (indentation is not possible for the first item).
    3. 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+Tab inside an <li>:

    1. The plugin identifies the parent <li> containing the current nested list.
    2. It moves the current <li> to be a sibling of the parent <li> (outdenting).
    3. If the item is the first or only item in the sublist, the entire nested list structure is removed.
    4. 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.

  9. How Data URI to Blob conversion works

    main

    To 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 call editor.value, the plugin automatically restores the original base64 strings.
    • Transparency: The conversion is handled internally. You can retrieve the original data via editor.value or editor.getElementValue(), but editor.getNativeEditorValue() will show the blob: 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>
  10. How the Sticky Plugin works

    main

    The 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 sizeSM configuration option (defaulting to 768px). If toolbarDisableStickyForMobile is true, 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).