SunEditor Documentation

repository·master·Indexed 24 days ago

https://github.com/jihong88/suneditor

A lightweight, fast, and extensible WYSIWYG web editor built with vanilla JavaScript. SunEditor features a modular plugin architecture, a layered CoreKernel design using a dependency injection container, and official wrappers for React and Vue. It is designed for modern web applications and supports structured content validation via strictMode.

Tokens
82.1K
Snippets
99
Records
251
Agent score
83%

What's inside suneditor

  1. Overview of SunEditor Plugin Types

    master

    SunEditor uses a class-based plugin system where different base classes determine the UI behavior and required lifecycle methods of your plugin. Choose the base class that matches your intended user interaction:

    Base Classstatic typeRequired MethodsUI Behavior
    PluginCommandcommandaction()Button click executes action
    PluginDropdowndropdownaction()Button opens menu, item click calls action()
    PluginDropdownFreedropdown-freeButton opens menu, plugin handles own events
    PluginModalmodalopen()Button opens modal dialog
    PluginBrowserbrowseropen(), close()Button opens gallery browser
    PluginFieldfieldResponds to editor input events
    PluginInputinputToolbar input element
    PluginPopuppopupshow()Inline popup context menu
  2. SunEditor Browser Support and Compatibility

    master

    SunEditor is built for modern browsers and does not include polyfills by default. It is optimized for structured content (articles, documentation, emails) and validates/auto-corrects content to maintain consistency.

    Supported Browsers (or newer)

    • Chrome: 119+
    • Edge: 119+
    • Firefox: 125+
    • Safari (macOS, iOS): 17.2+
    • Opera: 105+
    • Android WebView: 119+
    • Samsung Internet: 23.0+
    • Firefox ESR: 128+

    Not Supported

    • Internet Explorer (IE)
    • Legacy Edge

    Legacy Support

    If you require support for IE11, you must use the v2-legacy branch of SunEditor.

  3. SunEditor Directory Structure Overview

    master

    The project is organized into several functional layers:

    • src/core/: The engine of the editor, containing the kernel, config, logic (DOM, shell, panel), event orchestration, and schema definitions.
    • src/plugins/: Feature-specific implementations categorized by type (e.g., command, dropdown, modal, browser, field, input, popup).
    • src/modules/: Core structural components including contract (Modal, Controller, etc.), manager (FileManager, ApiManager), and ui utilities.
    • src/helper/: Pure utility functions, primarily DOM utilities.
    • src/langs/ & src/themes/: Internationalization files and CSS theme files.
    • types/: Generated TypeScript definitions.
    • test/: Test suites for unit, integration, and E2E testing.
  4. Use Component Launchers for lightweight components

    master

    Not every selectable component needs to be a full plugin. For lightweight components that only require basic actions like deletion (e.g., pageBreak), you can use a Component Launcher.

    A launcher is a stand-in for a plugin that is registered directly as a component-checker in the pluginManager.

    Key Rules for Launchers:

    • Hook-name contract: A launcher must use the same hook names as a full plugin: componentDestroy, componentSelect, and componentDeselect.
    • When to use: Use a launcher when the component has no UI beyond basic actions (like delete). Promote to a full plugin only if the component needs a Controller or complex actions, as a Controller can only be owned by a full plugin instance.
    // Example of a component-checker returning a launcher
    this.#componentCheckers.push((element) => {
        if (!element || !dom.utils.hasClass(element, 'se-page-break')) return null;
        /** @type {SunEditor.ComponentLauncher} */
        const launcher = {
            componentDestroy: (target) => {
                /* remove + refocus + history.push */
            },
        };
        return { target: element, launcher };
    });
  5. Use Markdown View mode

    master

    SunEditor includes a Markdown View mode that uses GitHub Flavored Markdown (GFM). It converts the editor's HTML to a JSON tree and then to a GFM string for editing.

    Supported Syntax:

    • Headings (# to ######), paragraphs, line breaks
    • Bold, italic, strikethrough, inline code, highlight
    • Ordered/unordered lists, task lists (- [x])
    • Blockquotes (>), fenced code blocks, horizontal rules (---)
    • Links, images, tables (pipe syntax)

    Usage:

    • Toggle via the markdownView button in the toolbar.
    • Programmatically via editor.viewer.markdownView().

    Note: Code View and Markdown View are mutually exclusive.

  6. How SunEditor is architected

    master

    SunEditor uses a layered architecture centered around a Dependency Injection (DI) container called the CoreKernel. This design allows the editor to remain zero-dependency (no external frameworks like React or jQuery) while managing complex state and logic through a centralized system.

    High-Level Layers

    1. Factory Entry Point (suneditor.js): Validates options and target elements to create the editor instance.
    2. Facade (editor.js): The main Editor class that orchestrates initialization, plugin lifecycles, and multi-root management. It exposes a minimal public API and the $ (Deps) object for deep access.
    3. CoreKernel (L1): The central orchestrator containing:
      • Store: Manages internal state and editing mode.
      • $ (Deps bag): A single object containing all dependencies shared with consumers.
      • L2 Config Providers: Handles context, options, instance checks, and event management.
      • L3 Business Logic: Divided into dom (selection, formatting), shell (components, history, plugins), and panel (toolbar, menus).
      • L4 Event Orchestrator: Manages the flow from handlers to reducers, rules, executors, and effects.
    graph TD
        User[User Code] --> Factory[suneditor.js]
        Factory --> Facade[editor.js]
        Facade --> Kernel[CoreKernel - L1]
    
        subgraph Core Kernel
            Kernel --> Store[Store - State]
            Kernel --> Config[L2 Config Providers]
            Kernel --> Logic[L3 Business Logic]
            Kernel --> Event[L4 Event Orchestrator]
        end
    
        Logic --> DOM[dom - Selection, Format ...]
        Logic --> Shell[shell - Component, History ...]
        Logic --> Panel[panel - Toolbar, Menu, Viewer]
    
        Event --> Handlers
        Event --> Reducers
        Event --> Rules
        Event --> Executor[Actions - Executor]
        Event --> Effects
  7. Access dependencies via the Deps bag ($)

    master

    All consumers (plugins, modules, etc.) must access dependencies through the Deps bag, represented by the $ symbol. Never import other L3 modules directly or reach into the kernel object itself, except for kernel.$ and kernel.store in core constructors.

    • Plugins: Obtain $ via super(kernel) (auto-injected by KernelInjector).
    • L3 / L4 modules: Store kernel.$ in a private #$ field via constructor(kernel).
    • Modules: Receive $ directly in the constructor: constructor(host, $, element, ...).
  8. Follow SunEditor dependency and layer boundaries

    master

    The project enforces strict import boundaries via .dependency-cruiser.js. When writing code, adhere to these rules:

    • helper/*: Cannot import from core/*, modules/*, or plugins/*.
    • modules/*: Cannot import from core/* or plugins/*. They must access other modules via the $ object passed in the constructor.
    • L3 Modules: Cannot import other L3 modules directly; use cross-references via $.
    • Plugins: Cannot import other plugins (though submodules within the same plugin are allowed).

    Correct way to access other modules:

    // Inside a class, reach other L3 modules through $:
    this.$.format.setLine(...);
    this.$.selection.getRange();
  9. Access editor services via the Dependency Bag (`this.$`)

    master

    All plugins interact with the editor through this.$, which is the Dependency Bag (Deps bag).

    Important: this.$ is not the Kernel itself; it is the dependency context provided by the Kernel. It contains all the services, configuration, and DOM logic required for plugin operation.

    Core Service Categories:

    • Config: Access global options, frameOptions, context, and localization/icons via this.$.lang and this.$.icons.
    • DOM Logic: Manipulate the editor using this.$.selection, this.$.html, this.$.format, this.$.inline, and this.$.nodeTransform.
    • Shell Logic: Manage lifecycle and state via this.$.pluginManager, this.$.commandDispatcher, this.$.history (undo/redo), and this.$.ui.
    • Panel Logic: Control the this.$.toolbar, this.$.menu, and this.$.viewer.
    • Services: Use this.$.eventManager for events, this.$.store for state, and this.$.facade to access the public editor API.
  10. Understand Multi-Root Architecture

    master

    SunEditor uses a unified frame architecture that supports both single-root and multi-root editing environments.

    Data Storage

    All editor instances (frames) are stored in a frameRoots Map within the core $ object.

    • Single-root: The rootKey is null.
    • Multi-root: Each root has a unique rootKey mapping to its own FrameContext.

    Core Components

    • $.frameRoots: The primary storage for all FrameContext data.
    • $.context: A global shared UI context (toolbars, status bars, modals).
    • $.frameContext & $.frameOptions: Pointers to the currently active frame's context and options.

    Frame Switching

    You can switch the active editing context using editor.changeFrameContext(rootKey). This updates the internal store.rootKey and resets the current frame pointers.

  11. How the SunEditor architecture works

    master

    SunEditor uses a layered architecture to separate core runtime, configuration, business logic, and event processing.

    • L1 (Kernel): The runtime container, state management (Store), and the dependency bag ($).
    • L2 (Config): Handles configuration, context, options, and the event API.
    • L3 (Logic): Contains business logic, DOM operations, and UI components (e.g., Selection, Toolbar, History).
    • L4 (Event): Manages internal DOM event processing via an orchestrator.

    When you call suneditor.create(), the editor follows a strict initialization order: validating targets, merging options, building the DOM, initializing the CoreKernel (which sets up the Store and dependency injection), registering plugins, and finally initializing the editor frames.

  12. Understand the SunEditor Architecture

    master

    SunEditor is a modular WYSIWYG editor built with vanilla JavaScript (ES2022+) and no runtime dependencies. It uses a central orchestration model to manage state, configuration, and features.

    Core Components

    • Kernel (CoreKernel): The central runtime container responsible for initialization, dependency injection (DI), and managing the lifecycle.
    • Deps ($): A shared dependency bag (accessible via kernel.$ or this.$) that contains all services. Note: The Deps object is not the Kernel itself.
    • Store: The central runtime state management (e.g., tracking mode, focus, and selection cache).
    • Config: Manages context providers, option providers, and event management.
    • Logic: Handles DOM operations (selection, formatting), shell operations (history, focus), and Panel UI (toolbar, menus).
    • Event: A Redux-like orchestration system using actions, handlers, reducers, and effects.
    • Plugins & Modules: Features like image or video are implemented as plugins, while structural components like Modal or ColorPicker are implemented as modules.