Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0d5817e
Fix inputs and values attachments to be data-first
gohabereg Apr 17, 2026
c5ff274
Merge branch 'main' of github.com:editor-js/document-model into fix/i…
gohabereg Apr 17, 2026
e4c246d
Load adapters as plugin
gohabereg Apr 26, 2026
40a6409
Merge branch 'main' of github.com:editor-js/document-model into fix/i…
gohabereg Apr 26, 2026
abe46db
Fix tests
gohabereg Apr 27, 2026
40c4284
Review comments
gohabereg Apr 27, 2026
ba5077d
(try to) fix test run for core package
gohabereg Apr 27, 2026
e424775
Run base branch coverage manually
gohabereg Apr 27, 2026
5990de3
Fix unit-tests action: use ArtiomTr with pre-generated coverage files
gohabereg Apr 27, 2026
208c95d
Try just PR branch tests
gohabereg Apr 28, 2026
0996eac
Try clear before build
gohabereg Apr 28, 2026
8958a51
Try no cache
gohabereg Apr 28, 2026
0ea33bc
Use latest node
gohabereg Apr 28, 2026
d265bd3
Review comments resolved
gohabereg Apr 29, 2026
7fe438f
Resolve review comments
gohabereg May 2, 2026
0ad4ae1
Add destoryBlockToolAdapter method to Adapter plugin
gohabereg May 3, 2026
9eb123a
Block ID implementation
gohabereg May 3, 2026
bb7fc7c
Fix lint
gohabereg May 3, 2026
f6702e4
Fix tests
gohabereg May 3, 2026
b4cbdfa
Fix build
gohabereg May 3, 2026
a5fa55f
Remove userId from getBlockSerialized method
gohabereg May 3, 2026
8235392
Fix call in the block manager
gohabereg May 3, 2026
ad55c9f
Move all tool's static configuration properties to the single options…
gohabereg May 4, 2026
855bc02
review comments
gohabereg May 4, 2026
d696d9f
Review comments
gohabereg May 5, 2026
e727e7e
Merge branch 'main' of github.com:editor-js/document-model into featu…
gohabereg May 7, 2026
0c1a951
Merge branch 'feature/block-id' into feature/tool-options
gohabereg May 7, 2026
c0e2d79
Merge branch 'main' into feature/tool-options
gohabereg May 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import {
EventBus,
type InlineToolConstructor,
PluginType,
ToolType
ToolType,
type ToolStaticOptions
} from '@editorjs/sdk';
import type { ToolSettings } from './tools/ToolsFactory';
import { composeDataFromVersion2 } from './utils/composeDataFromVersion2.js';
import ToolsManager from './tools/ToolsManager.js';
import type { CoreConfigValidated, CoreConfig, EditorjsPluginConstructor, BlockTuneConstructor, ToolConstructable, EditorjsAdapterPluginConstructor } from '@editorjs/sdk';
Expand Down Expand Up @@ -126,9 +126,9 @@ export default class Core {
/**
* Injects Tool constructor and options into the container
* @param tool - Tool constructor class (static `options` defines defaults merged with the second argument)
* @param options - feature flags, `config` for the tool plugin, etc.
* @param options - Overrides for the tool's static `options` (toolbox, title, config, shortcuts, etc.)
*/
public use(tool: ToolConstructable, options?: Omit<ToolSettings, 'class'>): Core;
public use(tool: ToolConstructable, options?: ToolStaticOptions): Core;
/**
* Injects Plugin into the container to initialize on Editor's init
* @param plugin - allows to pass any implementation of editor plugins
Expand All @@ -141,15 +141,15 @@ export default class Core {
*/
public use(
pluginOrTool: ToolConstructable | EditorjsPluginConstructor | EditorjsAdapterPluginConstructor,
options?: Omit<ToolSettings, 'class'>
options?: ToolStaticOptions
): Core {
const pluginType = pluginOrTool.type;

switch (pluginType) {
case ToolType.Block:
case ToolType.Inline:
case ToolType.Tune:
this.#plugins.bind<[ToolConstructable, ToolSettings | undefined]>(pluginType).toConstantValue([pluginOrTool as ToolConstructable, options as ToolSettings | undefined]);
this.#plugins.bind<[ToolConstructable, ToolStaticOptions | undefined]>(pluginType).toConstantValue([pluginOrTool as ToolConstructable, options]);
break;
case PluginType.Adapter:
if (this.#plugins.isBound(PluginType.Adapter)) {
Expand Down Expand Up @@ -193,9 +193,9 @@ export default class Core {
* Initalizes loaded tools
*/
async #initializeTools(): Promise<void> {
const blockTools = this.#plugins.getAll<[BlockToolConstructor, ToolSettings]>(ToolType.Block);
const inlineTools = this.#plugins.getAll<[InlineToolConstructor, ToolSettings]>(ToolType.Inline);
const blockTunes = this.#plugins.getAll<[BlockTuneConstructor, ToolSettings]>(ToolType.Tune);
const blockTools = this.#plugins.getAll<[BlockToolConstructor, ToolStaticOptions | undefined]>(ToolType.Block);
const inlineTools = this.#plugins.getAll<[InlineToolConstructor, ToolStaticOptions | undefined]>(ToolType.Inline);
const blockTunes = this.#plugins.getAll<[BlockTuneConstructor, ToolStaticOptions | undefined]>(ToolType.Tune);

return this.#toolsManager.prepareTools([...blockTools, ...inlineTools, ...blockTunes]);
}
Expand Down
15 changes: 7 additions & 8 deletions packages/core/src/tools/ToolsFactory.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
/* eslint-disable jsdoc/informative-docs */
import type { EditorAPI } from '@editorjs/sdk';
import { ToolType } from '@editorjs/sdk';
import type { ToolConstructable } from '@editorjs/sdk';
import type { ToolConstructable, ToolStaticOptions } from '@editorjs/sdk';
import {
InlineToolFacade,
BlockTuneFacade,
BlockToolFacade
} from '@editorjs/sdk';
import type {
EditorConfig,
ToolSettings as ToolSettingsV2
EditorConfig
} from '@editorjs/editorjs';

type ToolConstructor = typeof InlineToolFacade | typeof BlockToolFacade | typeof BlockTuneFacade;

/**
* Need this utility type to override some V2 options
* Full tool registration entry: the constructor class plus its options.
*/
export type ToolSettings = Omit<ToolSettingsV2, 'constructable' | 'class'> & {
export type ToolSettings = ToolStaticOptions & {
/**
* Redefine constructable to match V3
* Tool's constructor
*/
class: ToolConstructable;
};
Expand Down Expand Up @@ -70,10 +69,10 @@ export class ToolsFactory {
* Register tools in the factory
* @param tools - tools to register in the factory
*/
public setTools(tools: [ToolConstructable, ToolSettings][]): void {
public setTools(tools: [ToolConstructable, ToolStaticOptions | undefined][]): void {
tools.forEach(([tool, settings]) => {
this.#toolsSettings.set(tool.name, {
...settings,
...(settings ?? {}),
class: tool,
});
});
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/tools/ToolsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
ToolFacadeClass,
ToolsCollection,
EventBus,
ToolConstructable
type ToolConstructable,
type ToolStaticOptions
} from '@editorjs/sdk';

/**
Expand Down Expand Up @@ -105,7 +106,7 @@ export default class ToolsManager {
* Calls tools prepare method if it exists and adds tools to relevant collection (available or unavailable tools)
* @param tools - tools to prepare and their settings
*/
public async prepareTools(tools: [ToolConstructable, ToolSettings][]): Promise<void> {
public async prepareTools(tools: [ToolConstructable, ToolStaticOptions | undefined][]): Promise<void> {
const promiseQueue = new PromiseQueue();

const setToAvailableToolsCollection = (toolName: string, tool: ToolFacadeClass): void => {
Expand Down
9 changes: 8 additions & 1 deletion packages/core/src/tools/internal/inline-tools/bold/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,19 @@ export class BoldInlineTool implements InlineTool {
*/
public static type = ToolType.Inline as const;

public static title = 'Bold';
/**
* Tool name used to identify the tool across the editor.
*/
public static name = 'bold';

/**
* Predefined options (can be overriden on connection)
*/
public static readonly options = {
/**
* Tool title shown in the inline toolbar
*/
title: 'Bold',
/**
* Shortcuts plugin options
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,19 @@ export class ItalicInlineTool implements InlineTool {
*/
public static type = ToolType.Inline as const;

public static title = 'Italic';
/**
* Tool name used to identify the tool across the editor.
*/
public static name = 'italic';

/**
* Default options (merged with second argument of `use(ItalicInlineTool, options)`).
*/
public static readonly options = {
/**
* Tool title shown in the inline toolbar
*/
title: 'Italic',
/**
* Shortcuts plugin options
*/
Expand Down
15 changes: 14 additions & 1 deletion packages/core/src/tools/internal/inline-tools/link/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,20 @@ export class LinkInlineTool implements InlineTool {
*/
public static type = ToolType.Inline as const;

public static title = 'Link';
/**
* Tool name used to identify the tool across the editor.
*/
public static name = 'link';

/**
* Default options (merged with second argument of `use(LinkInlineTool, options)`).
*/
public static readonly options = {
/**
* Tool title shown in the inline toolbar
*/
title: 'Link',
};

/**
* Type of behaviour of the tool if new selection range intersect with existing fragment
Expand Down
93 changes: 77 additions & 16 deletions packages/sdk/src/entities/BaseTool.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,96 @@
import type { ToolConfig } from '@editorjs/editorjs';
import type { BlockToolOptions } from './BlockTool.js';
import type { InlineToolOptions } from './InlineTool.js';
import type { BlockTuneOptions } from './BlockTune.js';
import type { ToolType } from './EntityType.js';

/**
* Common interface for Tools static properties
* Canonical keys shared by every tool options interface.
*/
export interface BaseToolConstructor<Config extends ToolConfig = ToolConfig> {
export enum BaseToolOptionKey {
/**
* Default tool options (`static get options()`) provided by the tool developer.
* Plugin-specific configuration object passed to the tool instance.
*/
options?: {
/**
* Internal tool configuration
*/
config?: Record<string, unknown>;
Config = 'config'
}

/**
* Options common to every tool type.
* @template Config - Shape of the plugin-specific {@link BaseToolOptionKey.Config} object.
*/
export interface BaseToolOptions<Config extends ToolConfig = ToolConfig> {
/**
* Plugin-specific configuration passed to the tool instance.
* Defaults set here are merged with (and overridden by) the `config` key
* in the second argument of `core.use(Tool, options)`.
*/
[BaseToolOptionKey.Config]?: Config;
}

/**
* Other tool options
*/
[key: string]: unknown;
};
// Re-export so consumers can import all option types from this file
export type { BlockToolOptions, InlineToolOptions, BlockTuneOptions };

/**
* Union of all per-tool option shapes.
* Used as the type of the second argument of `core.use(Tool, options)`.
*/
export type ToolStaticOptions = BlockToolOptions | InlineToolOptions | BlockTuneOptions;

/**
* Maps a {@link ToolType} value to its corresponding tool options interface.
* @example
* function getTitle<T extends ToolType>(type: T, options: ToolTypeToOptions[T]) { ... }
*/
export type ToolTypeToOptions = {
/**
* BlockTool Options
*/
[ToolType.Block]: BlockToolOptions;
/**
* InlineTool Options
*/
[ToolType.Inline]: InlineToolOptions;
/**
* BlockTune Options
*/
[ToolType.Tune]: BlockTuneOptions;
};

/**
* Common interface for Tool constructor (static) side.
* @template Config - Shape of the plugin-specific config object. Passed to
* {@link prepare} and used to type {@link options.config}.
* @template Options - The concrete options interface for this tool type
* (defaults to the generic {@link BaseToolOptions}).
*/
export interface BaseToolConstructor<
Config extends ToolConfig = ToolConfig,
Options extends BaseToolOptions<Config> = BaseToolOptions<Config>
> {
/**
* Tool name used to identify the tool across the editor.
* Falls back to the JavaScript class name if not explicitly set.
*/
name: string;

/**
* All static configuration for the tool.
* Values here are defaults; they can be overridden via the second argument
* of `core.use(Tool, options)`.
*/
options?: Options;

/**
* Tool's prepare method. Can be async
* Tool's prepare method. Can be async.
* @param data - Object with toolName and config properties
* @param data.toolName - Tool's own name
* @param data.config - Tool's configuration
* @param data.config - Merged plugin configuration
*/
// eslint-disable-next-line -- ESLint doesn't understand it's a type
prepare?(data: { toolName: string, config: Config }): void | Promise<void>;

/**
* Tool's reset method to clean up anything set by prepare. Can be async
* Tool's reset method to clean up anything set by prepare. Can be async.
*/
reset?(): void | Promise<void>;
}
Loading
Loading