### Tool Constructor Example Source: https://github.com/codex-team/editor.js/blob/next/docs/tools.md Example of a Tool's constructor, showing how to access `data`, `config`, and `api` parameters. ```javascript constructor({data, config, api}) { this.data = data; this.api = api; this.config = config; // ... } ``` -------------------------------- ### Initialize Editor.js with Tools Source: https://context7.com/codex-team/editor.js/llms.txt Import Editor.js and necessary tools, then create an instance with configuration. This example includes Header and List tools. ```javascript import EditorJS from '@editorjs/editorjs'; import Header from '@editorjs/header'; import List from '@editorjs/list'; const editor = new EditorJS({ holder: 'editorjs', tools: { header: { class: Header, inlineToolbar: true, config: { placeholder: 'Enter a header', levels: [2, 3, 4], defaultLevel: 2 }, shortcut: 'CMD+SHIFT+H' }, list: { class: List, inlineToolbar: true, shortcut: 'CMD+SHIFT+L' } }, data: { blocks: [ { type: 'header', data: { text: 'Welcome to Editor.js', level: 2 } }, { type: 'paragraph', data: { text: 'Start typing your content here...' } } ] }, autofocus: true, placeholder: 'Let\'s write an awesome story!', onReady: () => { console.log('Editor.js is ready!'); }, onChange: (api, event) => { console.log('Content changed:', event); } }); // Wait for editor to be ready await editor.isReady; ``` -------------------------------- ### Editor.js Initialization with Tools Source: https://github.com/codex-team/editor.js/blob/next/docs/tools.md Example of initializing Editor.js with custom tools, including inline toolbar configuration. ```javascript var editor = new EditorJS({ holder : 'editorjs', tools: { text: { class: Text, inlineToolbar : true, // other settings.. }, header: Header }, defaultBlock : 'text', }); ``` -------------------------------- ### Initialize Editor.js Source: https://github.com/codex-team/editor.js/blob/next/index.html Initializes the Editor.js instance with a configuration object. Refer to the installation documentation for more details. ```javascript var editor = new EditorJS(editorConfig); ``` -------------------------------- ### Install Editor.js via npm Source: https://github.com/codex-team/editor.js/blob/next/docs/installation.md Use npm to install the Editor.js package. This is the recommended method for Node.js projects. ```shell npm i @editorjs/editorjs ``` -------------------------------- ### Tool Static Prepare Method Source: https://github.com/codex-team/editor.js/blob/next/docs/tools.md Example of a static `prepare` method within a Tool class, used for loading external scripts or setting up DOM nodes. ```javascript class Tool { static prepare(config) { loadScript(); insertNodes(); ... } } ``` -------------------------------- ### Block Tunes Output Format Example Source: https://github.com/codex-team/editor.js/blob/next/docs/block-tunes.md Demonstrates the structure of the output object when Block Tunes are used, showing how tune data is stored in the `tunes` property of each block. ```json { blocks: [ { type: 'paragraph', data: { text: 'This is paragraph with Tune' }, tunes: { 'my-tune-name': {}, favorite: true, anchor: 'might be string' } } ] } ``` -------------------------------- ### Sanitizer API Usage Example Source: https://github.com/codex-team/editor.js/blob/next/docs/api.md Demonstrates how to use the Sanitizer API to clean HTML strings with custom configurations. Ensure to provide appropriate configurations to prevent security vulnerabilities. ```javascript let taintString = '

BlockWithText

' let customConfig = { b: true, p: { style: true, }, } this.api.sanitizer.clean(taintString, customConfig); ``` -------------------------------- ### Editor.js Inline Code Example Source: https://github.com/codex-team/editor.js/blob/next/example/example.html Demonstrates the usage of inline code formatting within a paragraph. This is typically handled by the InlineCode tool. ```html Web clients ``` -------------------------------- ### Tool Static Reset Method Source: https://github.com/codex-team/editor.js/blob/next/docs/tools.md Example of a static `reset` method within a Tool class, used for cleaning up resources when the editor is destroyed. ```javascript class Tool { static reset() { cleanUpScripts(); deleteNodes(); ... } } ``` -------------------------------- ### Implement a Custom Block Tune in ES6 Source: https://github.com/codex-team/editor.js/blob/next/docs/toolbar-settings.md Example of creating a custom block tune using ES6 syntax. This class implements the necessary `render` and `save` methods, and its constructor accepts `api` and `settings`. ```javascript export default class YourCustomTune { constructor({api, settings}) { this.api = api; this.settings = settings; } render() { let someHTML = '...'; return someHTML; } save() { // Return the important data that needs to be saved return object } someMethod() { // moves current block down this.api.blocks.moveDown(); } } ``` -------------------------------- ### Save Editor Content to JSON Source: https://context7.com/codex-team/editor.js/llms.txt Use the save() method to get the editor's content as a JSON object. This example includes error handling and sending data to a server. ```javascript const editor = new EditorJS({ holder: 'editorjs', tools: { /* ... */ } }); // Save editor content async function saveContent() { try { const outputData = await editor.save(); console.log('Saved data:', JSON.stringify(outputData, null, 2)); // Output format: // { // "time": 1635603431943, // "blocks": [ // { // "id": "sheNwCUP5A", // "type": "header", // "data": { // "text": "Editor.js", // "level": 2 // } // }, // { // "id": "12iM3lqzcm", // "type": "paragraph", // "data": { // "text": "Hey. Meet the new Editor." // } // } // ], // "version": "2.31.6" // } // Send to server await fetch('/api/save', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(outputData) }); } catch (error) { console.error('Saving failed:', error); } } ``` -------------------------------- ### Implement a Custom Block Tune in TypeScript Source: https://github.com/codex-team/editor.js/blob/next/docs/toolbar-settings.md Example of creating a custom block tune by extending `IBlockTune` in TypeScript. Requires implementing `render` and `save` methods. The constructor receives `api` and `settings` objects. ```typescript import IBlockTune from './block-tune'; export default class YourCustomTune implements IBlockTune { public constructor({api, settings}) { this.api = api; this.settings = settings; } render() { let someHTML = '...'; return someHTML; } save() { // Return the important data that needs to be saved return object } someMethod() { // moves current block down this.api.blocks.moveDown(); } } ``` -------------------------------- ### Custom String to Tool Data Conversion Source: https://github.com/codex-team/editor.js/blob/next/docs/tools.md Use a function for the 'import' rule to define custom logic for converting an imported string into your Tool's data object. This example splits the string by dots to create a list of items. ```javascript class ListTool { constructor(data){ this.data = data || { items: [], type: 'unordered' } } static get conversionConfig() { return { // ... export rule /** * In this example, List Tool creates items by splitting original text by a dot symbol. */ import: (string) => { const items = string.split('.'); return { items: items.filter( (text) => text.trim() !== ''), type: 'unordered' }; } }; } } ``` -------------------------------- ### Use API Shorthands for Focus and Save Source: https://github.com/codex-team/editor.js/blob/next/docs/api.md Editor.js provides convenient shorthands for frequently used API methods. For example, `editor.focus()` is an alias for `editor.caret.focus()` and `editor.save()` for `editor.saver.save()`. ```javascript const editor = EditorJS(); editor.focus(); editor.save(); ``` -------------------------------- ### Configure Sanitization for Tune HTML Markup Source: https://github.com/codex-team/editor.js/blob/next/docs/block-tunes.md Provide a static `sanitize` getter to configure how HTML markup inserted by your Tune is handled, preventing it from being trimmed on save. This example allows `sup` tags. ```javascript class Tune { static get sanitize() { return { sup: true } } } ``` -------------------------------- ### Prepare Tune Data with Static Prepare Method Source: https://github.com/codex-team/editor.js/blob/next/docs/block-tunes.md Use the static `prepare` method to load external scripts or create HTML nodes when a Tune is initialized. It receives the Tune's configuration object. ```javascript class Tune { static prepare(config) { loadScript(); insertNodes(); ... } } ``` -------------------------------- ### Import Editor.js in JavaScript Source: https://github.com/codex-team/editor.js/blob/next/docs/installation.md Import the EditorJS module into your JavaScript application after installation via npm. ```javascript import EditorJS from '@editorjs/editorjs'; ``` -------------------------------- ### Initialize Editor.js with Zero Configuration Source: https://github.com/codex-team/editor.js/blob/next/docs/installation.md Create a new Editor.js instance with minimal configuration. It will use default settings and the Paragraph Tool. ```javascript var editor = new EditorJS(); /** Zero-configuration */ ``` ```javascript // equals var editor = new EditorJS('editorjs'); ``` -------------------------------- ### Initialize Editor.js with Configuration Object Source: https://github.com/codex-team/editor.js/blob/next/docs/installation.md Create a new Editor.js instance by passing a configuration object. This allows specifying the holder, tools, and initial data. ```javascript 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: {} }); ``` -------------------------------- ### Caret API Source: https://context7.com/codex-team/editor.js/llms.txt Controls cursor position within the editor, allowing navigation to specific blocks and positions (start, end, or custom offset). ```APIDOC ## Caret API ### Description Controls cursor position within the editor, allowing navigation to specific blocks and positions (start, end, or custom offset). ### Methods #### `editor.caret.focus(option)` - **Description**: Set focus to the editor. - **Parameters**: - **option** (boolean) - Optional - If true, focus at the end of the content. Defaults to false. #### `editor.caret.setToFirstBlock(position)` - **Description**: Set the caret to the beginning of the first block. - **Parameters**: - **position** (string) - Optional - The position within the block ('start', 'end', 'default'). Defaults to 'default'. - **Returns**: `boolean` - True if successful, false otherwise. #### `editor.caret.setToLastBlock(position)` - **Description**: Set the caret to the end of the last block. - **Parameters**: - **position** (string) - Optional - The position within the block ('start', 'end', 'default'). Defaults to 'default'. #### `editor.caret.setToBlock(blockIndex, position, offset)` - **Description**: Set the caret to a specific block and position. - **Parameters**: - **blockIndex** (number) - Required - The index of the target block. - **position** (string) - Required - The position within the block ('start', 'end', 'default'). - **offset** (number) - Optional - Character offset from the specified position. #### `editor.caret.setToNextBlock(position)` - **Description**: Move the caret to the beginning of the next block. - **Parameters**: - **position** (string) - Optional - The position within the next block ('start', 'end', 'default'). Defaults to 'default'. #### `editor.caret.setToPreviousBlock(position)` - **Description**: Move the caret to the end of the previous block. - **Parameters**: - **position** (string) - Optional - The position within the previous block ('start', 'end', 'default'). Defaults to 'default'. ``` -------------------------------- ### Initialize Editor.js Source: https://github.com/codex-team/editor.js/blob/next/example/example-i18n.html Initialize the Editor by creating a new instance with a configuration object. Ensure the holder element exists in your HTML. ```javascript var editor = new EditorJS({ holder: 'editorjs', tools: { paragraph: { config: { placeholder: "Enter something" } }, header: { class: Header, inlineToolbar: ['link'], config: { placeholder: 'Header' }, shortcut: 'CMD+SHIFT+H' }, image: ImageTool, list: { class: EditorjsList, inlineToolbar: true, shortcut: 'CMD+SHIFT+L' }, quote: { class: Quote, inlineToolbar: true, config: { quotePlaceholder: 'Enter a quote', captionPlaceholder: 'Quote\'s author', }, shortcut: 'CMD+SHIFT+O' }, warning: Warning, marker: { class: Marker, shortcut: 'CMD+SHIFT+M' }, code: { class: CodeTool, shortcut: 'CMD+SHIFT+C' }, delimiter: Delimiter, inlineCode: { class: InlineCode, shortcut: 'CMD+SHIFT+C' }, linkTool: LinkTool, embed: Embed, table: { class: Table, inlineToolbar: true, shortcut: 'CMD+ALT+T' }, }, i18n: { messages: { ui: { blockTunes: { toggler: { "Click to tune": "Нажмите, чтобы настроить", "or drag to move": "или перетащите" }, }, inlineToolbar: { converter: { "Convert to": "Конвертировать в" } }, toolbar: { toolbox: { Add: "Добавить", } }, popover: { Filter: "Поиск", "Nothing found": "Ничего не найдено", "Convert to": "Конвертировать в" } }, toolNames: { "Text": "Параграф", "Heading": "Заголовок", "Ordered List": "Нумерованный список", "Unordered List": "Маркированный список", "Warning": "Примечание", "Checklist": "Чеклист", "Quote": "Цитата", "Code": "Код", "Delimiter": "Разделитель", "Raw HTML": "HTML-фрагмент", "Table": "Таблица", "Link": "Ссылка", "Marker": "Маркер", "Bold": "Полужирный", "Italic": "Курсив", "InlineCode": "Моноширинный", "Image": "Картинка" }, tools: { warning: { "Title": "Название", "Message": "Сообщение" }, link: { "Add a link": "Вставьте ссылку" }, stub: { 'The block can not be displayed correctly.': 'Блок не может быть отображен' }, image: { "Caption": "Подпись", "Select an Image": "Выберите файл", "With border": "Добавить рамку", "Stretch image": "Растянуть", "With background": "Добавить подложку", }, code: { "Enter a code": "Код", }, linkTool: { "Link": "Ссылка", "Couldn't fetch the link data": "Не удалось получить данные", "Couldn't get this link data, try the other one": "Не удалось получить данные по ссылке, попробуйте другую", "Wrong response format from the server": "Неполадки на сервере", }, header: { "Heading 1": "Заголовок 1", "Heading 2": "Заголовок 2", "Heading 3": "Заголовок 3", "Heading 4": "Заголовок 4", "Heading 5": "Заголовок 5", "Heading 6": "Заголовок 6", }, paragraph: { "Enter something": "Введите текст" }, list: { "Ordered": "Нумерованный", "Unordered": "Маркированный", "Checklist": "Чеклист", } } } } }); ``` -------------------------------- ### Tool Preparation and Reset Source: https://github.com/codex-team/editor.js/blob/next/docs/tools.md Static methods for preparing and cleaning up resources associated with Tools. ```APIDOC ## Tool Prepare and Reset ### static prepare(config: Object) _optional_ Use this static method to prepare data for the Tool (e.g., load external scripts, create HTML nodes). ```javascript class Tool { static prepare(config) { loadScript(); insertNodes(); // ... } } ``` ### static reset() _optional_ Use this static method to clean up all prepared data when the Editor is destroyed. ```javascript class Tool { static reset() { cleanUpScripts(); deleteNodes(); // ... } } ``` Both `prepare` and `reset` methods can be asynchronous. ``` -------------------------------- ### User Configuration Source: https://github.com/codex-team/editor.js/blob/next/docs/tools.md How users can configure Tools when initializing the Editor. ```APIDOC ## User Configuration Tools can be configured by users via the `tools` property in the Editor Config. ```javascript var editor = new EditorJS({ holder : 'editorjs', tools: { text: { class: Text, inlineToolbar : true, // other settings.. }, header: Header }, defaultBlock : 'text', }); ``` ### Editor Config Options - **inlineToolbar** (Boolean/Array) - Default: `false`. Enable the Inline Toolbar with all Tools, or pass an array with specified Tools list. - **config** (Object) - User's configuration for the Plugin. ``` -------------------------------- ### Initialize Editor.js Instance Source: https://github.com/codex-team/editor.js/blob/next/README.md Import the EditorJS class and create a new instance, providing the target element ID and an object of tools to be used. ```javascript import EditorJS from '@editorjs/editorjs' const editor = new EditorJS({ tools: { // ... your tools } }) ``` -------------------------------- ### Handle HTML Tags with Attributes for Pasting Source: https://github.com/codex-team/editor.js/blob/next/docs/tools.md To preserve specific attributes from pasted HTML tags, define them within the `tags` configuration. This example shows how to keep the 'src' attribute for `` tags. ```javascript static get pasteConfig() { return { tags: [ { img: { src: true } } ], } } ``` -------------------------------- ### Editor.js Ready Callback using onReady Property Source: https://github.com/codex-team/editor.js/blob/next/docs/installation.md Use the `onReady` property in the configuration object to execute a function once the Editor.js instance is fully initialized. ```javascript var editor = new EditorJS({ // Other configuration properties /** * onReady callback */ onReady: () => {console.log('Editor.js is ready to work!')} }); ``` -------------------------------- ### Editor.js Callbacks for Ready and Change Events Source: https://github.com/codex-team/editor.js/blob/next/docs/installation.md Configure `onReady` and `onChange` callbacks during Editor.js initialization to react to editor readiness and content changes. ```javascript var editor = new EditorJS({ // Other configuration properties /** * onReady callback */ onReady: () => {console.log('Editor.js is ready to work!')}, /** * onChange callback * Accepts CustomEvent describing what happened */ onChange: (editorAPI, event) => {console.log('Now I know that Editor\'s content changed!')} }); ``` -------------------------------- ### Control Cursor Position with Caret API Source: https://context7.com/codex-team/editor.js/llms.txt The Caret API allows programmatic control over the cursor's position within the editor. Use 'start', 'end', or a character offset for precise placement. ```javascript const editor = new EditorJS({ /* config */ }); await editor.isReady; // Set focus to the editor (optionally at the end) editor.caret.focus(true); // true = focus at end // Set caret to first block const success = editor.caret.setToFirstBlock('start'); // Set caret to last block at end position editor.caret.setToLastBlock('end'); // Set caret to specific block by index editor.caret.setToBlock(2, 'start', 0); // Set caret with character offset editor.caret.setToBlock(0, 'start', 5); // 5 characters from start // Navigate to next/previous block editor.caret.setToNextBlock('start'); editor.caret.setToPreviousBlock('end'); // Position options: 'start', 'end', 'default' // offset: number of characters to shift from position ``` -------------------------------- ### Editor.js Ready with Async/Await Source: https://github.com/codex-team/editor.js/blob/next/docs/installation.md Use `async/await` syntax with the `isReady` promise for a more synchronous-looking code flow when handling Editor.js initialization. ```javascript var editor = new EditorJS(); try { await editor.isReady; /** Do anything you need after editor initialization */ } catch (reason) { console.log(`Editor.js initialization failed because of ${reason}`) } ``` -------------------------------- ### Editor Initialization and Configuration Source: https://github.com/codex-team/editor.js/blob/next/example/example-i18n.html Initializes the Editor.js instance with basic configuration and an onReady callback. The 'saveButton' click event is used to trigger the save operation. ```javascript var editor = new Editor({ holder: "editorjs", data: { blocks: [ { type: "header", data: { text: "Editor.js", level: 2 } }, { type: 'paragraph', data: { text: 'Hey. Meet the new Editor. On this page you can see it in action — try to edit this text. Source code of the page contains the example of connection and configuration.' } }, { type: "header", data: { text: "Key features", level: 3 } }, { type: 'list', data: { items: [ 'It is a block-styled editor', 'It returns clean data output in JSON', 'Designed to be extendable and pluggable with a simple API' ], style: 'unordered' } }, { type: "header", data: { text: "What does it mean «block-styled editor»", level: 3 } }, { type: 'paragraph', data: { text: 'Workspace in classic editors is made of a single contenteditable element, used to create different HTML markups. Editor.js workspace consists of separate Blocks: paragraphs, headings, images, lists, quotes, etc. Each of them is an independent contenteditable element (or more complex structure) provided by Plugin and united by Editor\'s Core.' } }, { type: 'paragraph', data: { text: `There are dozens of ready-to-use Blocks and the simple API for creation any Block you need. For example, you can implement Blocks for Tweets, Instagram posts, surveys and polls, CTA-buttons and even games. ` } }, { type: "header", data: { text: "What does it mean clean data output", level: 3 } }, { type: 'paragraph', data: { text: 'Classic WYSIWYG-editors produce raw HTML-markup with both content data and content appearance. On the contrary, Editor.js outputs JSON object with data of each Block. You can see an example below' } }, { type: 'paragraph', data: { text: `Given data can be used as you want: render with HTML for Web clients, render natively for mobile apps, create markup for Facebook Instant Articles or Google AMP, generate an audio version and so on. ` } }, { type: 'paragraph', data: { text: 'Clean data is useful to sanitize, validate and process on the backend.' } }, { type: 'delimiter', data: {} }, { type: 'paragraph', data: { text: 'We have been working on this project more than three years. Several large media projects help us to test and debug the Editor, to make its core more stable. At the same time we significantly improved the API. Now, it can be used to create any plugin for any task. Hope you enjoy. 😏' } }, { type: 'image', data: { file: { url: 'assets/codex2x.png' }, caption: '', stretched: false, withBorder: true, withBackground: false } } ] }, onReady: function() { saveButton.click(); } }); ``` -------------------------------- ### Set Caret Position in Block Source: https://github.com/codex-team/editor.js/blob/next/docs/caret.md Use this method to place the caret within a specific block at a given position and offset. The 'position' parameter determines if the caret is at the start, end, or default location within the block's text node. ```javascript Caret.setToBlock(block, position, offset) ``` -------------------------------- ### Initialize Editor.js with Header Tool Source: https://github.com/codex-team/editor.js/blob/next/example/example-popup.html Instantiates Editor.js with a specific tool configuration. Requires the Header tool to be imported and passed in the tools object. The 'holder' property specifies the DOM element ID for the editor. ```javascript var editor1 = new EditorJS({ holder: 'editorjs', tools: { header: { class: Header, shortcut: 'CMD+SHIFT+H' } } }); ``` -------------------------------- ### Initialize Editor.js with RTL Support Source: https://github.com/codex-team/editor.js/blob/next/example/example-rtl.html Use this configuration to set the text direction to RTL. Ensure the 'holder' ID matches your HTML element. ```javascript var editor = new EditorJS({ holder: 'editorjs', i18n: { direction: 'rtl', }, tools: { header: { class: Header, inlineToolbar: ['link'], config: { placeholder: 'Header' }, shortcut: 'CMD+SHIFT+H' }, image: { class: SimpleImage, inlineToolbar: ['link'], }, checklist: { class: Checklist, inlineToolbar: true, }, quote: { class: Quote, inlineToolbar: true, config: { quotePlaceholder: 'Enter a quote', captionPlaceholder: 'Quote\'s author', }, shortcut: 'CMD+SHIFT+O' }, warning: Warning, marker: { class: Marker, shortcut: 'CMD+SHIFT+M' }, code: { class: CodeTool, shortcut: 'CMD+SHIFT+C' }, delimiter: Delimiter, inlineCode: { class: InlineCode, shortcut: 'CMD+SHIFT+C' }, linkTool: LinkTool, raw: RawTool, embed: Embed, table: { class: Table, inlineToolbar: true, shortcut: 'CMD+ALT+T' }, }, data: { blocks: [ { type: "header", data: { text: "محرر.js", level: 2 } }, { type : 'paragraph', data : { text : 'مرحبا! تعرف على المحرر الجديد. في هذه الصفحة ، يمكنك رؤيتها في العمل - حاول تحرير هذا النص.' } }, { type: "header", data: { text: "دلائل الميزات", level: 3 } }, { type : 'list', data : { items : [ 'وهو محرر بنمط الكتلة', 'تقوم بإرجاع إخراج بيانات نظيفة في JSON', 'مصممة لتكون قابلة للتوسيع والتوصيل مع واجهة برمجة تطبيقات بسيطة' ], style: 'unordered' } } ] }, onReady: function(){ saveButton.click(); }, onChange: function() { console.log('something changed'); } }); ``` -------------------------------- ### Load Editor.js locally Source: https://github.com/codex-team/editor.js/blob/next/docs/installation.md Copy the editor.js file into your project and load it using a script tag in your HTML. ```html ``` -------------------------------- ### Create an Inline Marker Tool Source: https://context7.com/codex-team/editor.js/llms.txt Implement a custom inline tool for applying 'MARK' formatting. Requires render(), surround(), and checkState() methods. The tool is configured with a specific tag and class for styling and identification. ```javascript class MarkerTool { static get isInline() { return true; } static get title() { return 'Marker'; } static get sanitize() { return { mark: { class: 'cdx-marker' } }; } constructor({ api }) { this.api = api; this.button = null; this.tag = 'MARK'; this.class = 'cdx-marker'; } render() { this.button = document.createElement('button'); this.button.type = 'button'; this.button.innerHTML = ''; this.button.classList.add('ce-inline-tool'); return this.button; } surround(range) { if (!range) return; const termWrapper = this.api.selection.findParentTag(this.tag, this.class); if (termWrapper) { this.unwrap(termWrapper); } else { this.wrap(range); } } wrap(range) { const marker = document.createElement(this.tag); marker.classList.add(this.class); marker.appendChild(range.extractContents()); range.insertNode(marker); this.api.selection.expandToTag(marker); } unwrap(termWrapper) { this.api.selection.expandToTag(termWrapper); const selection = window.getSelection(); const range = selection.getRangeAt(0); const unwrappedContent = range.extractContents(); termWrapper.parentNode.removeChild(termWrapper); range.insertNode(unwrappedContent); selection.removeAllRanges(); selection.addRange(range); } checkState() { const termTag = this.api.selection.findParentTag(this.tag, this.class); this.button.classList.toggle('ce-inline-tool--active', !!termTag); return !!termTag; } } // Usage const editor = new EditorJS({ tools: { marker: MarkerTool }, // Enable inline toolbar for paragraph inlineToolbar: ['bold', 'italic', 'marker', 'link'] }); ``` -------------------------------- ### Editor.js Ready Promise Handling Source: https://github.com/codex-team/editor.js/blob/next/docs/installation.md Utilize the `isReady` promise of the Editor.js instance to perform actions after initialization. Handles both success and failure scenarios. ```javascript var editor = new EditorJS(); editor.isReady .then(() => { /** Do anything you need after editor initialization */ }) .catch((reason) => { console.log(`Editor.js initialization failed because of ${reason}`) }); ``` -------------------------------- ### Inline Tool Base Structure and Methods Source: https://github.com/codex-team/editor.js/blob/next/docs/tools-inline.md This section details the fundamental properties and methods required for creating an Inline Tool, along with optional methods for enhanced functionality. ```APIDOC ## Inline Tool API Documentation ### Base Structure To create an Inline Tool, the Tool's class must have a static getter `isInline` set to `true`. ### Required Methods - `render()`: Creates and returns the button element for the Inline Toolbar. - `surround(range: Range)`: Works with the selected text range to apply formatting or actions. - `checkState(selection: Selection)`: Detects and returns the activated state of the Tool based on the current selection. ### Optional Methods - `renderActions()`: Creates and returns an additional element to be displayed below the toolbar buttons (e.g., for inputs). - `clear()`: Contains logic to clear tool-specific states or elements when the Inline Toolbar opens or closes. - `sanitize()`: Defines the sanitizer configuration for the HTML tags used by the Tool. ### Constructor Parameter The constructor of a Tool's class instance accepts an object with the [API](api.md) as a parameter. --- ### `render()` **Description:** Method that returns a button to append at the Inline Toolbar. **Parameters:** Method does not accept any parameters. **Return Value:** - **Type:** `HTMLElement` - **Description:** Element that will be added to the Inline Toolbar. --- ### `surround(range: Range)` **Description:** Method that accepts a selected range and wraps it somehow. **Parameters:** - **`range`** (Range) - Required - The first range of the current selection. **Return Value:** There is no return value. --- ### `checkState(selection: Selection)` **Description:** Gets the current selection and detects if the Tool was applied. This allows the Tool to highlight its button or show details. **Parameters:** - **`selection`** (Selection) - Required - The current selection object. **Return Value:** - **Type:** `Boolean` - **Description:** `true` if the Tool is active, otherwise `false`. --- ### `renderActions()` **Description:** Optional method that returns an additional `HTMLElement` with actions. For example, an input for the 'link' tool or a textarea for the 'comment' tool. It will be placed below the buttons list in the Inline Toolbar. **Parameters:** Method does not accept any parameters. **Return Value:** - **Type:** `HTMLElement` - **Description:** Element that will be added to the Inline Toolbar. --- ### `clear()` **Description:** Optional method that will be called on opening or closing of the Inline Toolbar. Can contain logic for clearing Tool's stuff, such as inputs, states, and other. **Parameters:** Method does not accept any parameters. **Return Value:** Method should not return a value. --- ### `static get sanitize()` **Description:** Specifies the Sanitizer configuration corresponding to the inline tags used by your Tool. This configuration will be merged with the sanitizer configuration of the Block Tool using the Inline Toolbar. **Example:** If your Tool wraps selected text with a `` tag, the sanitizer config should look like this: ```javascript static get sanitize() { return { b: {} // {} means clean all attributes. true — leave all attributes } } ``` Read more about Sanitizer configuration at the [Tools#sanitize](tools.md#sanitize). --- ### `static get title()` **Description:** Specifies the Tool's title via a static getter. This can be used, for example, in a tooltip with an icon description that appears on hover. **Example:** ```javascript export default class BoldInlineTool implements InlineTool { /** * Specifies Tool as Inline Toolbar Tool * * @return {boolean} */ public static isInline = true; /** * Title for hover-tooltip */ public static title: string = 'Bold'; // ... other methods } ``` ``` -------------------------------- ### Block Tune Base Structure and Methods Source: https://github.com/codex-team/editor.js/blob/next/docs/block-tunes.md Defines the fundamental structure and methods required for a Block Tune, including rendering settings, wrapping block content, saving tune data, and static preparation/cleanup methods. ```APIDOC ## Block Tune Structure and Methods A Block Tune is a feature that allows you to add custom options and behaviors to Blocks in Editor.js. It requires a static `isTune` property set to `true` and an implementation of the `render()` method. ### `render()` - **Description**: Creates and returns an `HTMLElement` to be displayed in the Block's settings panel. - **Parameters**: None - **Returns**: `HTMLElement` - The element to be appended to the block settings area. ### `wrap(blockContent: HTMLElement): HTMLElement` - **Description**: Wraps the Block's content with custom HTML elements, allowing modification of the Block's appearance. - **Parameters**: - `blockContent` (HTMLElement) - The current content of the Block, potentially wrapped by other Tunes. - **Returns**: `HTMLElement` - The new wrapper element for the Block's content. ### `save()` - **Description**: Returns the current state of the Tune, which will be saved as part of the Editor's output. - **Parameters**: None - **Returns**: `any` - The data to be saved for this Tune. ### `static prepare(config: object)` - **Description**: A static method used for preparing data or resources before the Tune is used. It receives the Tune's configuration. - **Parameters**: - `config` (object) - The configuration object for the Tune. - **Returns**: None ### `static reset()` - **Description**: A static method called when the Editor is destroyed, used for cleaning up any resources prepared by the `prepare()` method. - **Parameters**: None - **Returns**: None ### `static get sanitize()` - **Description**: A static getter that returns a sanitization configuration object. This is crucial if the Tune inserts HTML markup into the Block's content to prevent it from being trimmed during saving. Refer to the [sanitizer page](sanitizer.md) for more details. - **Returns**: `object` - Sanitization configuration. #### Example `sanitize` configuration: ```javascript static get sanitize() { return { sup: true } } ``` ``` -------------------------------- ### Configure Tool Shortcuts in Editor.js Source: https://github.com/codex-team/editor.js/blob/next/docs/usage.md Specify custom keyboard shortcuts for tools like Header and List when initializing Editor.js. Ensure the tool class is imported. ```javascript var editor = new EditorJS({ //... tools: { header: { class: Header, shortcut: 'CMD+SHIFT+H' }, list: { class: List, shortcut: 'CMD+SHIFT+L' } } //... }); ``` -------------------------------- ### Clean Up Tune Data with Static Reset Method Source: https://github.com/codex-team/editor.js/blob/next/docs/block-tunes.md Implement the static `reset` method to clean up any prepared data, such as scripts or nodes, when the Editor is destroyed. ```javascript class Tune { static reset() { cleanUpScripts(); deleteNodes(); ... } } ``` -------------------------------- ### ToolbarAPI Source: https://github.com/codex-team/editor.js/blob/next/docs/api.md API for controlling the main editor toolbar. ```APIDOC ### ToolbarAPI Methods that working with Toolbar `open()` - opens toolbar `close()` - closes toolbar, toolbox and blockSettings if they are opened ``` -------------------------------- ### Create a Block Alignment Tune Source: https://context7.com/codex-team/editor.js/llms.txt Implement a custom block tune for text alignment. This tune requires render() and save() methods, and optionally wrap() to modify block appearance. It supports 'left', 'center', and 'right' alignments. ```javascript class AlignmentTune { static get isTune() { return true; } static get sanitize() { return { div: { 'data-alignment': true } }; } constructor({ api, data, config, block }) { this.api = api; this.block = block; this.config = config; this.data = data || { alignment: 'left' }; this.wrapper = null; } render() { const alignments = ['left', 'center', 'right']; return alignments.map(alignment => ({ icon: this.getAlignIcon(alignment), label: `Align ${alignment}`, isActive: this.data.alignment === alignment, closeOnActivate: true, onActivate: () => { this.data.alignment = alignment; this.updateAlignment(); } })); } wrap(blockContent) { this.wrapper = document.createElement('div'); this.wrapper.classList.add('alignment-tune'); this.wrapper.dataset.alignment = this.data.alignment; this.wrapper.style.textAlign = this.data.alignment; this.wrapper.appendChild(blockContent); return this.wrapper; } updateAlignment() { if (this.wrapper) { this.wrapper.dataset.alignment = this.data.alignment; this.wrapper.style.textAlign = this.data.alignment; } } save() { return this.data; } getAlignIcon(alignment) { const icons = { left: '', center: '', right: '' }; return icons[alignment]; } } // Usage - Apply tune to specific tools const editor = new EditorJS({ tools: { paragraph: { class: Paragraph, tunes: ['alignment'] }, header: { class: Header, tunes: ['alignment'] }, alignment: { class: AlignmentTune } } }); // Or apply globally to all blocks const editor2 = new EditorJS({ tools: { /* ... */ }, tunes: ['alignment'] }); // Saved output format: // { // "blocks": [{ // "type": "paragraph", // "data": { "text": "Centered text" }, // "tunes": { "alignment": { "alignment": "center" } } // }] // } ``` -------------------------------- ### Load Editor.js from CDN Source: https://github.com/codex-team/editor.js/blob/next/docs/installation.md Include the Editor.js script from a CDN in your HTML. Replace the version number with the desired one. ```html ``` -------------------------------- ### Tool Conversion Configuration with Export Function Source: https://github.com/codex-team/editor.js/blob/next/docs/tools.md Use a function for the 'export' property to compose a custom string representation of the Tool's data for conversion. ```javascript static get conversionConfig() { return { export: (data) => { return data.items.join('.'); // in this example, all list items will be concatenated to an export string }, // ... import rule }; } ``` -------------------------------- ### Tooltip API Source: https://github.com/codex-team/editor.js/blob/next/docs/api.md Methods for showing Tooltip helper near elements, with options for placement, delay, and content. ```APIDOC ## Tooltip API Methods for showing Tooltip helper near your elements. Parameters are the same as in [CodeX Tooltips](http://github.com/codex-team/codex.tooltips) lib. ### `show` Method shows tooltip with custom content on passed element. ```javascript this.api.tooltip.show(element, content, options); ``` #### Parameters | parameter | type | description | | -- | -- | -- | | `element` | _HTMLElement_ | Tooltip will be showed near this element | | `content` | _String_ or _Node_ | Content that will be appended to the Tooltip | | `options` | _Object_ | Some displaying options, see below | #### Available showing options | name | type | action | | -- | -- | -- | | `placement` | `top`, `bottom`, `left`, `right` | Where to place the tooltip. Default value is `bottom' | | `marginTop` | _Number_ | Offset above the tooltip with `top` placement | | `marginBottom` | _Number_ | Offset below the tooltip with `bottom` placement | | `marginLeft` | _Number_ | Offset at left from the tooltip with `left` placement | | `marginRight` | _Number_ | Offset at right from the tooltip with `right` placement | | `delay` | _Number_ | Delay before showing, in ms. Default is `70` | | `hidingDelay` | _Number_ | Delay before hiding, in ms. Default is `0` | ### `hide` Method hides the Tooltip. ```javascript this.api.tooltip.hide(); ``` ### `onHover` Decorator for showing tooltip near some element by "mouseenter" and hide by "mouseleave". ```javascript this.api.tooltip.onHover(element, content, options); ``` ``` -------------------------------- ### Initialize Multiple Editor.js Instances Source: https://github.com/codex-team/editor.js/blob/next/example/example-multiple.html Use the `EditorJS` constructor to create separate instances. Each instance requires a unique `holder` ID to target its corresponding DOM element. Tools can be configured per instance. ```javascript /** * Instance #1 */ var editor1 = new EditorJS({ holder: 'editorjs1', tools: { header: { class: Header, shortcut: 'CMD+SHIFT+H' } } }); /** * Instance #2 */ var editor2 = new EditorJS({ holder: 'editorjs2', tools: { header: { class: Header, shortcut: 'CMD+SHIFT+H' } } }); ``` -------------------------------- ### Load Header Tool from CDN Source: https://github.com/codex-team/editor.js/blob/next/docs/installation.md Include the Header Tool script from a CDN. This allows you to use the Header block in your editor. ```html ```