A block-styled editor with clean JSON output

Overview

Backers on Open Collective Sponsors on Open Collective Join the chat at https://gitter.im/codex-team/editor.js

IE / Edge
IE / Edge
Firefox
Firefox
Chrome
Chrome
Safari
Safari
iOS Safari
iOS Safari
Opera
Opera
Edge 12+ Firefox 18+ Chrome 49+ Safari 10+ Safari 10+ Opera 36+

If you like a project πŸ’— πŸ’— πŸ’—

If you like Editor.js you can support project improvements and development of new features with a donation to our collective.

πŸ‘‰ https://opencollective.com/editorjs

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

Backers

Thank you to all our backers! πŸ™ [Become a backer]

Contributors

This project exists thanks to all the people who contribute.

We really welcome new contributors. If you want to make some code with us, please take a look at the Good First Tasks. You can write to us on [email protected] or via special Telegram chat, or any other way.

Documentation

Please visit https://editorjs.io/ to view all documentation articles.

You can join a Gitter-channel or Telegram-chat and ask a question.

Changelog

See the whole Changelog

How to use Editor.js

Basics

Editor.js is a Block-Styled editor. Blocks are structural units, of which the Entry is composed. For example, Paragraph, Heading, Image, Video, List are Blocks. Each Block is represented by Plugin. We have many ready-to-use Plugins and a simple API for creating new ones.

How to use the Editor after Installation.

  • Create new Blocks by pressing Enter or clicking the Plus Button
  • Press TAB or click on the Plus Button to view the Toolbox
  • Press TAB again to leaf Toolbox and select a Block you need. Then press Enter.

  • Select a text fragment and apply a style or insert a link from the Inline Toolbar

  • Use the Β«three-dotsΒ» button on the right to open Block Settings. From here, you can move and delete a Block or apply a Tool's settings, if it provided. For example, you can set a Heading level or List style.

Shortcuts

A few shortcuts are preset as available.

Shortcut Action Restrictions
TAB Show/leaf a Toolbox. On empty block
SHIFT+TAB Leaf back a Toolbox. While Toolbox is opened
ENTER Create a Block While Toolbox is opened and some Tool is selected
CMD+B Bold style On selection
CMD+I Italic style On selection
CMD+K Insert a link On selection

Each Tool can also have its own shortcuts. These are specified in the configuration of the Tool, for example:

var editor = new EditorJS({
  //...
  tools: {
    header: {
      class: Header,
      shortcut: 'CMD+SHIFT+H'
    },
    list: {
      class: List,
      shortcut: 'CMD+SHIFT+L'
    }
  }
  //...
 });

Installation Guide

There are few steps to run Editor.js on your site.

  1. Load Editor's core
  2. Load Tools
  3. Initialize Editor's instance

Step 1. Load Editor's core

Get Editor.js itself. It is a minified script with Editor's core and some default must-have tools.

Choose the most usable method of getting Editor for you.

  • Node package
  • Source from CDN
Option A. NPM install

Install the package via NPM or Yarn

npm i @editorjs/editorjs

Include module in your application

import EditorJS from '@editorjs/editorjs';
Option B. Use a CDN

You can load EditorJS directly from from jsDelivr CDN.

https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest

For example, place this in your HTML:

<script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest"></script>

Or download the bundle file and use it from your server.

<script src="editor.js"></script>

Step 2. Load the Tools that you want to make available

Each Block is represented by a Tool. Tools are simple external scripts with their own logic. For example, there is a Header Tool into which you type your heading text. If you want to be able to use this, install the Header Tool the same way as the Editor (Node.js, CDN, local file).

Example: use Header from CDN

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/bundle.js"></script>

Check Editor.js's community to see more ready-to-use Tools.

Step 3. Create Editor instance

Create an instance of Editor.js and pass Configuration Object with holderId and tools list.

<div id="editorjs"></div>

You can create a simple Editor with only default Paragraph Tool by passing a string with element's Id (wrapper for Editor) as a configuration param. Or use the default editorjs id for wrapper.

var editor = new EditorJS(); /** Zero-configuration */

// equals

var editor = new EditorJS('editorjs');

Or pass a whole settings object.

var editor = new EditorJS({
    /**
     * Create a holder for the Editor and pass its ID
     */
    holder : 'editorjs',

    /**
     * Available Tools list.
     * Pass Tool's class or Settings object for each Tool you want to use
     */
    tools: {
        header: {
          class: Header,
          inlineToolbar : true
        },
        // ...
    },

    /**
     * Previously saved data that should be rendered
     */
    data: {}
});

Saving Data

Call editor.save() and handle returned Promise with saved data.

editor.save()
  .then((savedData) => {
    console.log(savedData);
  });

Example

Take a look at the example.html to view more detailed examples.

Credits and references

About team

We are CodeX and we build products for developers and makers.

Follow us on Twitter: twitter.com/codex_team

Feel free to contact: [email protected]

codex.so

Comments
  • SSR support

    SSR support

    Can't use by node.js import in Next.js

    When I try to use by way of a Node.js import, I get an "ReferenceError: window is not defined" error in the browser and can't use it at all.

    It works fine when I load it by CDN in the head.

    opened by noahniuwa 25
  • Layout scheme

    Layout scheme

    • [ ] Create rows on render, by default each row have 1 column
    • [ ] Add ability to drag-n-drop block to the left or to the right of other block, creating several columns layout
    • [ ] Add id to each block to saved data blocks property
    • [ ] Add layout property to saved data object.

    The layout should describe layout scheme of Blocks by their ids. For example

    [---1---]
    [---2---]
    [ 3 ][ 4 ]
    [---5---]
    

    should be described as

    [1, 2, [3, 4], 5]
    
    feature 
    opened by neSpecc 19
  • Import raw HTML on init

    Import raw HTML on init

    Hi,

    is it possible to import custom HTML into EditorJS on initialization?

    For example - I have already existing HTML page, for which I need some WYSIWYG functionality.

    Currently when I do:

    <div id="page-content">
       <p>Hello</p>
       <p>World</p>
    </div>
    
    var editor = new EditorJS({
    	holder : 'page-content'
    });
    

    then existing content of element "page-content" is ignored, and editor is just appended at the end (e.g. page bottom). Creates new empty space rather than importing two existing <p> nodes - Hello and World.

    So it seems that EditosJS can only load supplied data of JSON blocks on initialization and cannot load any custom HTML contents. Is that correct or did I miss something .. ?

    I also looked over plugins - could not find any plugin for importing/parsing/loading supplied HTML.

    Thank you.

    discussion 
    opened by lubosdz 18
  • Unique id for each block

    Unique id for each block

    Hey, It would be great if editor assigned unique id for each block. This would help to keep references, add links to other blocks. This probably would introduce breaking changes, discussion would be needed before implementing.

    I have fork where I plan to do more changes, one of them is uids https://github.com/floatas/editor.js/commit/36c1f61ed66689bf9237ae3f37cc7e76e0658cb9

    opened by floatas 18
  • Support for column layout

    Support for column layout

    It would be great if blocks could be arranged in columns. Here is an example from Notion, where dragging a block to the left or right edge of another block positions them in a column layout.

    While dragging: ScreenCapture at Tue Apr 9 15:09:12 CEST 2019

    The result: ScreenCapture at Tue Apr 9 15:06:27 CEST 2019

    feature 
    opened by michaelfester 16
  • Support for i18n

    Support for i18n

    I'm trying to translate the editor tooltips and names to Portuguese, but the docs don't specify a way to do that, and in fact, it doesn't seem possible at the moment.

    Can this be done?

    important 
    opened by matheusgrieger 15
  • Fix for EditorJS nesting

    Fix for EditorJS nesting

    By nesting Editor.js, it can design layouts more flexibly. I fixed some event handlers to nest Editor.js.

    Demo https://codesandbox.io/s/editor-js-grid-nest-ro2uz?fontsize=14&hidenavigation=1&theme=dark

    opened by hata6502 14
  • feat: Add unique ids for each block

    feat: Add unique ids for each block

    When editing documents collaboratively, we usually need a unique id to save and identify the current block. This PR is modified and resubmitted based on this #1333 , because this PR is no longer maintained

    I'm adressing #873 with this PR.

    Tested Features:

    • Existing data: If your previous block does not have an "id" property, it will create a new unique id
    • Existing data: If your previous block does have an "id" property, it will keep the existing unique id
    • Existing data: If a block gets changed the "id" property stays the same
    • Insert New Block: It will create a new unique id
    • Copy & Paste blocks: It will create a new unique ids per copied block
    • Move Blocks (Up/Down): It will keep the existing unique id

    Important Note:

    If you "transform/transition" an existing block to another block it will receive a NEW unique id

    not ready 
    opened by cobbcheng 13
  • Unable to use inside Shadow Dom and Webcomponents

    Unable to use inside Shadow Dom and Webcomponents

    We wanted to use EditorJS with customElements (we use lit-html internally). Our reasons behind this is because we wanted to isolate the editor styles away from the main dom so that our CMS styles don't make the editor content look strange. This way we can also customize the CSS nicely so that the end user looks at the formatting and text with about the same styles as they would on the frontend.

    We previously used a Iframe for this (which still works), but we would like to avoid that if possible.

    With the editor in the customElement, we get errors like these: editorjs_shadowdom

    Here is the code that creates the customElement:

    import '@editorjs/editorjs/dist/editor.js';
    import {LitElement, html, css} from 'lit-element';
    
    
    class HTMLEngine {
      constructor(inputEl, templateSelector, editorConfig) {
        this.inputEl = inputEl;
        this.editorConfig = editorConfig;
      }
    
      read() {
        let doc = new DOMParser().parseFromString(this.inputEl.value, 'text/html');
        var dataTemplate = doc.querySelector('[data-editor-data]');
        if (dataTemplate) {
          var jsonData = dataTemplate.dataset.editorData;
          return JSON.parse(jsonData);
        }
        return null;
      }
    
      write(outputData) {
        var editorData = JSON.stringify(outputData);
        var renderedBlocks = '';
        outputData.blocks.forEach((block) => {
          renderedBlocks += this.renderBlock(block);
        });
        this.inputEl.value = `<template data-editor-data='${editorData}'></template>
          ${renderedBlocks}`;
      }
    
      renderBlock(block) {
        return this.editorConfig.tools[block.type].HTMLGenerator(block.data) + '\n';
      }
    }
    
    
    class OstinatoEditorWidget extends LitElement {
      static get properties() {
        return {
          saveTo: { type: String },
          editorConfig: { type: String },
          editorFramePath: { type: String },
        }
      }
    
      constructor() {
        super();
        this.saveTo = '';
        this.editorConfig = '';
        this.editorFramePath = '';
      }
    
      connectedCallback() {
        super.connectedCallback();
        this.saveToEl = document.querySelector(this.saveTo);
        // Now import our editor config.
        import(this.editorConfig).then((m) => {
          this.config = m.editorConfig;
          this.engine = new HTMLEngine(
            this.saveToEl,
            '[editorjs-data]',
            this.config);
          this.initEditor();
        });
      }
    
      initEditor() {
        this.config.data = this.engine.read();
        this.config.holder = this.shadowRoot.getElementById('editor');
    
        this.config.onChange = function() {
          this.editor.save().then((outputData) => {
            if (outputData) this.engine.write(outputData);
          });
        }.bind(this);
    
        console.log(this.config);
    
        this.editor = new EditorJS(this.config);
      }
    
      static get styles() {
        return css`
          :host {
            display: block;
            width: 100%;
          }
    
          #editor {
            width: 100%;
            box-shadow: 0 0 1px 2px #e3e3e3;
          }
        `;
      }
    
      render() {
        return html`
          <div id="editor"></div>
        `;
      }
    }
    
    customElements.define('ostinato-editor-widget', OstinatoEditorWidget);
    

    And this is how we are using the element:

    {% load staticfiles %}
    
    <textarea name="{{ widget.name }}"
      {% include "django/forms/widgets/attrs.html" %}
      style="display: none;">{% if widget.value %}{{ widget.value }}{% endif %}</textarea>
    
    <ostinato-editor-widget
      saveTo='[name="{{ widget.name }}"]'
      editorConfig="{{ config_module }}">
    </ostinato-editor-widget>
    

    Edit: Oh and here is the config that is used.

    export const editorConfig = {
      initialBlock: "paragraph",
      minHeight: "400px",
      autoFocus: true,
    
      tools: {
        header: {
          class: Header,
          config: {
            placeholder: 'Header Text'
          },
          shortcut: 'CMD+SHIFT+H',
          HTMLGenerator: (data) => `<h${data.level}>${data.text}</h${data.level}>`,
        },
    
        paragraph: {
          class: Paragraph,
          shortcut: 'CMD+SHIFT+P',
          HTMLGenerator: (data) => `<p>${data.text}</p>`,
        },
    
        list: {
          class: List,
          inlineToolbar: true,
          shortcut: 'CMD+SHIFT+L',
          HTMLGenerator: (data) => {
            let tagname = data.style.charAt(0) + 'l';
            var renderItem = (item) => { return `<li>${item}</li>`; }
            var items = '';
            data.items.forEach((item) => { items += renderItem(item); });
            return `<${tagname}>${items}</${tagname}>`;
          },
        },
    
        quote: {
          class: Quote,
          inlineToolbar: true,
          config: {
            quotePlaceholder: 'Enter a quote',
            captionPlaceholder: 'Caption or Author',
          },
          shortcut: 'CMD+SHIFT+O',
          HTMLGenerator: (data) => {
            return `<blockquote style="quote-${data.alignment}">
              <p class="quote-text">${data.text}</p>
              <p class="quote-caption">${data.caption}</p>
            </blockquote>`;
          },
        },
    
        warning: {
          class: Warning,
          inlineToolbar: true,
          shortcut: 'CMD+SHIFT+W',
          config: {
            titlePlaceholder: 'Warning Title',
            messagePlaceholder: 'Warning Message',
          },
          HTMLGenerator: (data) => {
            return `<div class="warning">
                <p class="warning-title">${data.title}</p>
                <p class="warning-message">${data.message}</p>
              </div>`;
          },
        },
    
        marker: {
          class:  Marker,
          shortcut: 'CMD+SHIFT+M'
        },
    
        code: {
          class:  CodeTool,
          shortcut: 'CMD+SHIFT+C',
          HTMLGenerator: (data) => { return `<code>${data.code}</code>`; }
        },
    
        delimiter: {
          class: Delimiter,
          HTMLGenerator: () => { return `<div class="ce-delimiter"></div>` }
        },
    
        inlineCode: {
          class: InlineCode,
          shortcut: 'CMD+SHIFT+C'
        },
    
        table: {
          class: Table,
          inlineToolbar: true,
          shortcut: 'CMD+ALT+T',
          HTMLGenerator: (data) => {
            var rows = '';
            data.content.forEach((row) => {
              var cells = '';
              row.forEach((cell) => { cells += '<td>' + cell + '</td>'; })
              rows += '<tr>' + cells + '</tr>';
            });
            return '<table>' + rows + '</table>';
          }
        },
      },
    };
    
    
    discussion 
    opened by andrewebdev 13
  • Divide blocks into container blocks and leaf blocks

    Divide blocks into container blocks and leaf blocks

    Editor.js is an awesome project, both in design and implementation.

    But I need to nesting a block in other block.

    So I hope that you can divide blocks into container blocks and leaf blocks.

    opened by LinFeng1997 13
  • Block tunes as a popover

    Block tunes as a popover

    • Updates block tunes to use popover component. As a temporary solution, non-default block tunes are rendered as before and inserted to special area inside the popover.
    • New getter blockSettings (naming could be discussed) is added to tunes interface. It allows to configure the way tune is displayed in the popover.
    image important 
    opened by TatianaFomina 12
  • [Bug] Splitting a block does not create

    [Bug] Splitting a block does not create "block-changed" event on the source block.

    Describe a bug.

    If I click enter in somewhere in the block, a new block gets created from the caret position.

    However for the source block which got split, does not get a "block-changed" event.

    Steps to reproduce:

    1. Go to … Add some text to paragraph block.
    2. Click on … Click enter somewhere in middle of the text. A new block with content from the caret position get created
    3. …

    Expected behavior:

    • Block Added event for new block. βœ…
    • Block Changed event for the block which got split. ❌

    From the source code, only a insert operation is invoked which results in "block-added" event.

    https://github.com/codex-team/editor.js/blob/43032ebaac6a8b9a67c9bf2ada5adc0f8592d546/src/components/modules/blockManager.ts#L479 Screenshots:

    Device, Browser, OS:

    Editor.js version: 2.26.4

    Plugins you use with their versions:

    bug 
    opened by krisnik 0
  • Is there a way to always show the plus icon for the new line instead of on hovering❓

    Is there a way to always show the plus icon for the new line instead of on hovering❓

    The plus sign to show the toolbar is only visible when one hovers over a block which is fine for blocks that are already filled. But is there a way to to keep it visible for the next/new block, with no need to hover over it?

    discussion 
    opened by Dhruv69420 0
  • [Bug] Serious Issue Tab on Input opens the Menu after Update to v2.26.4

    [Bug] Serious Issue Tab on Input opens the Menu after Update to v2.26.4

    Describe a bug.

    Steps to reproduce:

    1. Go to https://editorjs.io/
    2. Click on Caption Input on Image
    3. Press Tab it is opening the Menu

    Expected behavior: It should not open the menu

    Screenshots:

    https://user-images.githubusercontent.com/2174170/209351479-aad24e35-1007-41ca-8b33-897d395d2221.mov

    Device, Browser, OS: Chrome

    Editor.js version: v2.26.4

    Plugins you use with their versions:

    bug 
    opened by khanakia 1
  • [Bug] When doing a block conversion, it strips all formatting

    [Bug] When doing a block conversion, it strips all formatting

    When I convert a paragraph to a header, for example, it strips all html tags.. including ones that should be saved by sanitize. Bold, italics, underline, links, and any other expected HTML gets stripped. This happens across all conversions that I've tested.

    Steps to reproduce:

    1. Go to editorjs.io
    2. Select any paragraph block that has alternative formatting (inline code, marker, links, etc)
    3. Convert it to a heading or quote, using the option available within the inline toolbar (on the left). You'll notice that all html tags are stripped and links, etc are lost.

    Expected behavior: html tags should be preserved and interpreted by the rules defined in the Tool Class it is transforming into. Perhaps ideally, it runs through the onPaste and/or Sanitize functions... rather than stripping all html.

    Screenshots: easy to reproduce on editorjs.io

    Device, Browser, OS: Macbook Pro, Mac OS 11.7, Chrome Version 108.0.5359.124 (Official Build) (x86_64)

    Editor.js version: @latest as of 12/22/22

    Plugins you use with their versions: Easily reproducable on editorjs.io

    Thank you!!

    bug 
    opened by ARH3 2
  • [Bug] BlockToolData should be imported as a type

    [Bug] BlockToolData should be imported as a type

    Describe a bug.

    Steps to reproduce: When I tried to release my app, the type check failed with following errors:

    error TS1371: This import is never used as a value and must use 'import type' because 'importsNotUsedAsValues' is set to 'error'.
    1 import {BlockToolData} from '../tools';
    node_modules/@editorjs/editorjs/types/configs/conversion-config.ts:1:9 - error TS1444: 'BlockToolData' is a type and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.
    1 import {BlockToolData} from '../tools';
              ~~~~~~~~~~~~~
    Found 2 errors in the same file, starting at: node_modules/@editorjs/editorjs/types/configs/conversion-config.ts:1
    ERROR: "type-check" exited with 1.
    

    Expected behavior:

    Screenshots: https://ibb.co/6vdy38T

    Device, Browser, OS: Debian linux, Vite 2.9.9

    Editor.js version: 2.26.4

    Plugins you use with their versions: "@editorjs/header": "^2.6.2", "@editorjs/list": "^1.7.0", "@editorjs/paragraph": "^2.8.0", "@editorjs/table": "^2.1.0", "@editorjs/underline": "^1.0.0"

    bug 
    opened by CODE-BR3AKER 1
  • Define new

    Define new "block-updated" event.

    The question.

    How to differentiate Block Update (vs) Block insert / delete.

    Why and how the question has come up.

    When block is updated using block.update(id, BlockToolData) - EditorJS onChange api gets called twice. once with blocked-removed and later with block-added events.

    block-removed and block-added events are also fired when the blocks are deleted / added to the EditorJS instance.

    Hence, from the onChange response, it is not possible to differentiate if block's content is updated or a new block is added / existing block is removed.

    discussion 
    opened by krisnik 0
Releases(v2.26.4)
  • v2.26.4(Dec 14, 2022)

  • v2.26.3(Dec 14, 2022)

  • v2.26.2(Dec 6, 2022)

  • v2.26.1(Dec 2, 2022)

  • v2.26.0(Nov 29, 2022)

    image
    • New β€” UI β€” Block Tunes became vertical just like the Toolbox 🀩
    • New β€” Block Tunes API β€” Now the render() method of a Block Tune can return the Menu Config with just icon, label, and callback instead of custom HTML. This improvement is key to the new straightforward way of configuring the tune's appearance in the Block Tunes menu.
    • New β€” Tools API β€” As well as render() in Tunes API, Tool's renderSettings() now also supports new configuration format.
    • New β€” UI β€” Meet the new icons from CodeX Icons pack πŸ› πŸ’
    • New β€” BlocksAPI β€” the blocks.insert() method now also have the optional id param. If passed, this id will be used instead of the generated one.
    • Deprecated β€” Styles API β€” CSS classes .cdx-settings-button and .cdx-settings-button--active are not recommended to use. Consider configuring your block settings with a new JSON API instead.
    • Improvement β€” Tools API β€” pasteConfig().tags now support sanitizing configuration. It allows you to leave some explicitly specified attributes for pasted content.
    • Improvement β€” CodeStyle β€” CodeX ESLint Config has bee updated. All ESLint/Spelling issues resolved
    • Improvement β€” ToolsAPI β€” The icon property of the toolbox getter became optional.
    • Fix β€” The wrong element is not highlighted anymore when the popover opened.
    • Fix β€” When Tunes Menu open keydown events can not be handled inside plugins.
    • Fix β€” If a Tool specifies some tags to substitute on paste, all attributes of that tags will be removed before passing them to the tool. Possible XSS vulnerability fixed.
    • Fix β€” Pasting from Microsoft Word to Chrome (Mac OS) fixed. Now if there are no image-tools connected, the regular text content will be pasted.
    • Fix β€” Workaround for the HTMLJanitor bug with Tables (https://github.com/guardian/html-janitor/issues/3) added
    • Fix β€” Toolbox shortcuts appearance and execution fixed #2112
    • Fix β€” Inline Tools click handling on mobile devices improved

    πŸ’Œ Read about the new Menu Config feature for defining Block Tunes menu appearance: https://codex.so/editorjs-menu-config

    Source code(tar.gz)
    Source code(zip)
    editor.js(451.45 KB)
  • v2.26.0-rc.7(Nov 28, 2022)

  • v2.26.0-rc.6(Nov 26, 2022)

    • New β€” UI β€” Meet the new icons from CodeX Icons pack πŸ› πŸ’
    • New β€” BlocksAPI β€” the blocks.insert() method now also have the optional id param. If passed, this id will be used instead of the generated one.
    • Fix β€” Pasting from Microsoft Word to Chrome (Mac OS) fixed. Now if there are no image-tools connected, regular text content will be pasted.
    • Improvement β€” CodeStyle β€” CodeX ESLint Config has bee updated. All ESLint/Spelling issues resolved
    Source code(tar.gz)
    Source code(zip)
    editor.js(452.06 KB)
  • v2.26.0-rc.1(Nov 21, 2022)

    • Fix β€” If a Tool specifies some tags to substitute on paste, all attributes of that tags will be removed before passing them to the tool. Possible XSS vulnerability fixed.
    • Fix β€” Workaround for the HTMLJanitor bug with Tables (https://github.com/guardian/html-janitor/issues/3) added
    • Improvement β€” Tools API β€” pasteConfig().tags now support sanitizing configuration. It allows you to leave some explicitly specified attributes for pasted content.
    Source code(tar.gz)
    Source code(zip)
    editor.js(389.13 KB)
  • v2.26.0-rc.0(Nov 3, 2022)

    • New β€” UI β€” Block Tunes became vertical just like the Toolbox 🀩
    • New β€” Block Tunes API β€” Now render() method of a Block Tune can return config with just icon, label and callback instead of custom HTML. This improvement is a key to the new straightforward way of configuring tune's appearance in Block Tunes menu.
    • New β€” Tools API β€” As well as render() in Tunes API, Tool's renderSettings() now also supports new configuration format.
    • Deprecated β€” Styles API β€” CSS classes .cdx-settings-button and .cdx-settings-button--active are not recommended to use. Consider configuring your block settings with new JSON API instead.
    • Fix β€” Wrong element not highlighted anymore when popover opened.
    • Fix β€” When Tunes Menu open keydown events can not be handled inside plugins.
    Source code(tar.gz)
    Source code(zip)
    editor.js(388.60 KB)
  • v2.25.0(Jun 22, 2022)

    • New β€” Tools API β€” Introducing new feature β€” toolbox now can have multiple entries for one tool! Due to that API changes: tool's toolbox getter now can return either a single config item or an array of config items
    • New β€” Blocks API β€” composeBlockData() method was added.

    🀘 Read the overview of the Multiple Toolbox items feature: https://codex.so/editorjs-toolbox

    Screenshot 2022-06-22 at 16 53 39 Source code(tar.gz)
    Source code(zip)
    editor.js(386.02 KB)
  • v2.24.3(May 6, 2022)

  • v2.24.2(May 1, 2022)

    • Fix β€” Scrolling issue when opening toolbox on mobile fixed
    • Fix β€” Typo in toolbox empty placeholder fixed
    • Fix β€” The issue with scroll jumping on block hovering have fixed 2036
    • Improvement β€” Dev Example Page - Add popup example page
    • Improvement β€” UI - The Toolbox will restore the internal scroll on every opening
    Source code(tar.gz)
    Source code(zip)
    editor.js(382.97 KB)
  • v2.24.1(Apr 28, 2022)

  • v2.24.0(Apr 26, 2022)

    • New β€” UI β€” The Toolbox became vertical πŸ₯³
    • Improvement β€” UI β€” the Plus button will always be shown (previously, it appears only for empty blocks)
    • Improvement β€” Dev Example Page - Server added to allow opening example page on other devices in network.
    • Fix β€” UI β€” the Toolbar won't move on hover at mobile viewports. Resolves #1972
    • Fix β€” OnChange event invocation after block insertion. #1997
    • Fix β€” ReadOnly β€” the readonly.isEnabled API getter now works correctly after readonly.toggle() calling. Resolves #1822
    • Fix β€” Paste β€” the inline HTML tags now will be preserved on pasting. #1686
    image Source code(tar.gz)
    Source code(zip)
    editor.js(381.44 KB)
  • v2.23.2(Feb 9, 2022)

  • v2.23.1(Feb 8, 2022)

  • v2.23.0-rc.2(Jan 25, 2022)

  • v2.23.0-rc.1(Nov 24, 2021)

    • Improvement β€” UI β€” Block Tunes toggler moved to the left
    • Improvement β€” UI β€” Block Actions (BT toggler + Plus Button) will appear on block hovering instead of click
    • Improvement β€” UI β€” Block Tunes toggler icon and Plus button icon updated
    • Improvement β€” Dev Example Page β€” The menu with helpful buttons added to the bottom of the screen
    • Improvement β€” Dev Example Page β€” The 'dark' theme added. Now we can code at night more comfortably.
    • Improvement β€” Rectangle Selection β€” paint optimized
    • Fix β€” Rectangle Selection β€” the first click after RS was not clear selection state. Now does.
    • Improvement β€” Blocks API β€” toolbar moving logic removed from blocks.move() and blocks.swap() methods. Instead, you should use Toolbar API (it was used by MoveUp and MoveDown tunes, they were updated).
    • New β€” Blocks API β€” The getBlockIndex() method added
    • New β€” Blocks API β€” the insert() method now has the replace: boolean parameter
    • New β€” Blocks API β€” the insert() method now returns the inserted Block API
    • New β€” Listeners API β€” the on() method now returns the listener id.
    • New β€” Listeners API β€” the new offById() method added
    • New β€” API β€” The new UiApi section was added. It allows accessing some editor UI nodes and methods.
    • Refactoring β€” Toolbox became a standalone class instead of a Module. It can be accessed only through the Toolbar module.
    • Refactoring β€” CI flow optimized.
    Source code(tar.gz)
    Source code(zip)
    editor.js(367.53 KB)
  • v2.23.0-rc.0(Oct 6, 2021)

    • Improvement β€” The onChange callback now accepts two arguments: EditorJS API and the CustomEvent with type and detail allowing to determine what happened with a Block
    • New Block API β€” The new dispatchChange() method allows to manually trigger the 'onChange' callback. Useful when Tool made a state mutation that is invisible for editor core.
    Source code(tar.gz)
    Source code(zip)
    editor.js(362.55 KB)
  • v2.23.0(Feb 7, 2022)

    • Improvement β€” EditorConfig β€” The onChange callback now accepts two arguments: EditorJS API and the CustomEvent with type and detail allowing to determine what happened with a Block
    • New β€” Block API β€” The new dispatchChange() method allows to manually trigger the 'onChange' callback. Useful when Tool made a state mutation that is invisible for editor core.
    • Improvement β€” UI β€” Block Tunes toggler moved to the left
    • Improvement β€” UI β€” Block Actions (BT toggler + Plus Button) will appear on block hovering instead of click
    • Improvement β€” UI β€” Block Tunes toggler icon and Plus button icon updated
    • Improvement β€” Dev Example Page β€” The menu with helpful buttons added to the bottom of the screen
    • Improvement β€” Dev Example Page β€” The 'dark' theme added. Now we can code at night more comfortably.
    • Improvement β€” Rectangle Selection β€” paint optimized
    • Fix β€” Rectangle Selection β€” the first click after RS was not clear selection state. Now does.
    • Improvement β€” Blocks API β€” toolbar moving logic removed from blocks.move() and blocks.swap() methods. Instead, you should use Toolbar API (it was used by MoveUp and MoveDown tunes, they were updated).
    • New β€” Blocks API β€” The getBlockIndex() method added
    • New β€” Blocks API β€” the insert() method now has the replace: boolean parameter
    • New β€” Blocks API β€” the insert() method now returns the inserted Block API
    • New β€” Listeners API β€” the on() method now returns the listener id.
    • New β€” Listeners API β€” the new offById() method added
    • New β€” API β€” The new UiApi section was added. It allows accessing some editor UI nodes and methods.
    • New β€” The Roadmap added to the Readme
    • Refactoring β€” Toolbox became a standalone class instead of a Module. It can be accessed only through the Toolbar module.
    • Refactoring β€” CI flow optimized.
    • Fix - Recognize async onPaste handlers in tools #1803.
    • Fix β€” Fire onChange event for native inputs #1750
    Source code(tar.gz)
    Source code(zip)
    editor.js(362.36 KB)
  • v2.22.3(Sep 20, 2021)

  • v2.22.2(Jul 21, 2021)

    • Improvement β€” Inline Toolbar might be used for any contenteditable element inside Editor.js zone
    • Improvement Tunes API - Tunes now can provide sanitize configuration
    • Fix Tunes API - Tune config now passed to constructor under config property
    • Fix Types - Add common type for internal and external Tools configuration
    • Fix β€” Block's destroy method is called on block deletion
    • Fix - Fix jump to the button of editor zone on CBS
    Source code(tar.gz)
    Source code(zip)
    editor.js(361.49 KB)
  • v2.22.1(Jun 28, 2021)

  • v2.22.0(May 26, 2021)

  • v2.21.0(Apr 28, 2021)

  • v2.20.2(Apr 15, 2021)

  • v2.20.1(Apr 9, 2021)

    • Fix - Create a new block when clicked at the bottom #1588.
    • Fix β€” Fix sanitisation problem with Inline Tools #1631
    • Fix β€” Fix copy in FireFox 1625
    • Refactoring - The Sanitizer module is util now.
    • Refactoring - Tooltip module is util now.
    • Refactoring β€” Refactoring based on LGTM #1577.
    • Refactoring β€” Refactoring based on ESLint #1636.
    Source code(tar.gz)
    Source code(zip)
    editor.js(358.26 KB)
  • v2.20.0(Apr 4, 2021)

  • v2.19.3(Mar 15, 2021)

  • v2.19.2(Mar 15, 2021)

    • New - toolbar.toggleBlockSettings() API method added #1442.
    • Improvements - A generic type for Tool config added #1516
    • Improvements - Remove unused force option in Caret.navigateNext() and Caret.navigatePrevious() #857.
    • Improvements - Remove bundles from the repo #1541.
    • Improvements - Document will be scrolled when blocks are selected with SHIFT+UP or SHIFT+DOWN #1447
    • Improvements - The caret will be set on editor copy/paste #1470
    • Improvements - Added generic types to OutputBlockData #1551.
    • Fix - Fix BlockManager.setCurrentBlockByChildNode() with multiple Editor.js instances #1503.
    • Fix - Fix an unstable block cut process #1489.
    • Fix - Type definition of the Sanitizer config: the sanitize function now contains param definition #1491.
    • Fix - Fix unexpected behavior on an empty link pasting #1348.
    • Fix - Fix SanitizerConfig type definition #1513
    • Fix - Editor Config now immutable #1552.
    • Fix - Fix bubbling on BlockManagers' listener #1433.
    • Refactoring - The Listeners module now is util.
    • Refactoring - The Events module now is util.
    • Refactoring - Shortcuts module is util now.
    Source code(tar.gz)
    Source code(zip)
    editor.js(350.17 KB)
Owner
CodeX
Team of web-development fans
CodeX
A markdown editor. http://lab.lepture.com/editor/

Editor A markdown editor you really want. Sponsors Editor is sponsored by Typlog. Overview Editor is not a WYSIWYG editor, it is a plain text markdown

Hsiaoming Yang 2.8k Dec 19, 2022
Override the rich text editor in Strapi admin with ToastUI Editor.

strapi-plugin-wysiwyg-tui-editor ⚠️ This is a strapi v4 plugin which does not support any earlier version! A Strapi plugin to replace the default rich

Zhuo Chen 12 Dec 23, 2022
A chrome extension which helps change ace editor to monaco editor in web pages, supporting all features including autocompletes.

Monaco-It Monaco-It is a chrome extension turning Ace Editor into Monaco Editor, supporting all features including autocompletes. δΈ€δΊ›δΈ­ζ–‡θ―΄ζ˜Ž Supported Lan

null 3 May 17, 2022
The next generation Javascript WYSIWYG HTML Editor.

Froala Editor V3 Froala WYSIWYG HTML Editor is one of the most powerful JavaScript rich text editors ever. Slim - only add the plugins that you need (

Froala 5k Jan 1, 2023
Simple rich text editor (contentEditable) for jQuery UI

Hallo - contentEditable for jQuery UI Hallo is a very simple in-place rich text editor for web pages. It uses jQuery UI and the HTML5 contentEditable

Henri Bergius 2.4k Dec 17, 2022
A modern, simple and elegant WYSIWYG rich text editor.

jQuery-Notebook A simple, clean and elegant WYSIWYG rich text editor for web aplications Note: Check out the fully functional demo and examples here.

Raphael Cruzeiro 1.7k Dec 12, 2022
Ace (Ajax.org Cloud9 Editor)

Ace (Ajax.org Cloud9 Editor) Note: The new site at http://ace.c9.io contains all the info below along with an embedding guide and all the other resour

Ajax.org B.V. 25.2k Jan 4, 2023
In-browser code editor

CodeMirror CodeMirror is a versatile text editor implemented in JavaScript for the browser. It is specialized for editing code, and comes with over 10

CodeMirror 25.6k Dec 30, 2022
Quill is a modern WYSIWYG editor built for compatibility and extensibility.

Note: This branch and README covers the upcoming 2.0 release. View 1.x docs here. Quill Rich Text Editor Quickstart β€’ Documentation β€’ Development β€’ Co

Quill 34.3k Jan 2, 2023
Medium.com WYSIWYG editor clone. Uses contenteditable API to implement a rich text solution.

If you would be interested in helping to maintain one of the most successful WYSIWYG text editors on github, let us know! (See issue #1503) MediumEdit

yabwe 15.7k Jan 4, 2023
Tiny bootstrap-compatible WISWYG rich text editor

bootstrap-wysiwyg Important information for Github requests/issues Please do not submit issues/comments to this repo. Instead, submit it to https://gi

MindMup 5.6k Jan 3, 2023
HTML5 rich text editor. Try the demo integration at

Squire Squire is an HTML5 rich text editor, which provides powerful cross-browser normalisation in a flexible lightweight package (only 16.5KB of JS a

Neil Jenkins 4.4k Dec 28, 2022
A rich text editor for everyday writing

Trix A Rich Text Editor for Everyday Writing Compose beautifully formatted text in your web application. Trix is a WYSIWYG editor for writing messages

Basecamp 17.3k Jan 3, 2023
A lightweight and amazing WYSIWYG JavaScript editor - 20kB only (8kB gzip)

Supporting Trumbowyg Trumbowyg is an MIT-licensed open source project and completely free to use. However, the amount of effort needed to maintain and

Alexandre Demode 3.8k Jan 7, 2023
Simple, beautiful wysiwyg editor

This repo is no longer maintained. bootstrap3-wysiwyg is much better Overview Bootstrap-wysihtml5 is a javascript plugin that makes it easy to create

James Hollingworth 4.2k Dec 30, 2022
Open source rich text editor based on HTML5 and the progressive-enhancement approach. Uses a sophisticated security concept and aims to generate fully valid HTML5 markup by preventing unmaintainable tag soups and inline styles.

This project isn’t maintained anymore Please check out this fork. wysihtml5 0.3.0 wysihtml5 is an open source rich text editor based on HTML5 technolo

Christopher Blum 6.5k Jan 7, 2023
Raptor, an HTML5 WYSIWYG content editor!

Raptor Editor Raptor Editor is a user-focused extensible WYSIWYG website content editor - check out the Demo. It is designed to be user and developer

PANmedia 533 Sep 24, 2022
Popline is an HTML5 Rich-Text-Editor Toolbar

popline Popline is a non-intrusive WYSIWYG editor that shows up only after selecting a piece of text on the page, inspired by popclip. Usage Load jQue

kenshin 1k Nov 4, 2022