2021-04-04 14:10:26 +02:00
|
|
|
import BaseTool, { InternalBlockToolSettings, ToolType, UserSettings } from './base';
|
2021-03-31 22:29:41 +02:00
|
|
|
import {
|
|
|
|
BlockAPI,
|
|
|
|
BlockTool as IBlockTool,
|
2021-04-04 14:10:26 +02:00
|
|
|
BlockToolConstructable,
|
2021-03-31 22:29:41 +02:00
|
|
|
BlockToolData,
|
|
|
|
ConversionConfig,
|
2022-06-17 17:31:55 +02:00
|
|
|
PasteConfig, SanitizerConfig, ToolboxConfig,
|
|
|
|
ToolboxConfigEntry
|
2021-03-31 22:29:41 +02:00
|
|
|
} from '../../../types';
|
|
|
|
import * as _ from '../utils';
|
2021-04-08 20:17:23 +02:00
|
|
|
import InlineTool from './inline';
|
|
|
|
import BlockTune from './tune';
|
|
|
|
import ToolsCollection from './collection';
|
2021-03-31 22:29:41 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Class to work with Block tools constructables
|
|
|
|
*/
|
|
|
|
export default class BlockTool extends BaseTool<IBlockTool> {
|
|
|
|
/**
|
|
|
|
* Tool type — Block
|
|
|
|
*/
|
|
|
|
public type = ToolType.Block;
|
|
|
|
|
2021-04-08 20:17:23 +02:00
|
|
|
/**
|
|
|
|
* InlineTool collection for current Block Tool
|
|
|
|
*/
|
|
|
|
public inlineTools: ToolsCollection<InlineTool> = new ToolsCollection<InlineTool>();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* BlockTune collection for current Block Tool
|
|
|
|
*/
|
|
|
|
public tunes: ToolsCollection<BlockTune> = new ToolsCollection<BlockTune>();
|
|
|
|
|
2021-04-04 14:10:26 +02:00
|
|
|
/**
|
|
|
|
* Tool's constructable blueprint
|
|
|
|
*/
|
|
|
|
protected constructable: BlockToolConstructable;
|
|
|
|
|
2021-03-31 22:29:41 +02:00
|
|
|
/**
|
|
|
|
* Creates new Tool instance
|
|
|
|
*
|
|
|
|
* @param data - Tool data
|
|
|
|
* @param block - BlockAPI for current Block
|
|
|
|
* @param readOnly - True if Editor is in read-only mode
|
|
|
|
*/
|
2021-04-04 14:10:26 +02:00
|
|
|
public create(data: BlockToolData, block: BlockAPI, readOnly: boolean): IBlockTool {
|
2021-03-31 22:29:41 +02:00
|
|
|
// eslint-disable-next-line new-cap
|
|
|
|
return new this.constructable({
|
|
|
|
data,
|
|
|
|
block,
|
|
|
|
readOnly,
|
2021-04-04 14:10:26 +02:00
|
|
|
api: this.api.getMethodsForTool(this),
|
2021-03-31 22:29:41 +02:00
|
|
|
config: this.settings,
|
|
|
|
}) as IBlockTool;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if read-only mode is supported by Tool
|
|
|
|
*/
|
|
|
|
public get isReadOnlySupported(): boolean {
|
|
|
|
return this.constructable[InternalBlockToolSettings.IsReadOnlySupported] === true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if Tool supports linebreaks
|
|
|
|
*/
|
|
|
|
public get isLineBreaksEnabled(): boolean {
|
|
|
|
return this.constructable[InternalBlockToolSettings.IsEnabledLineBreaks];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-06-17 17:31:55 +02:00
|
|
|
* Returns Tool toolbox configuration (internal or user-specified).
|
|
|
|
*
|
|
|
|
* Merges internal and user-defined toolbox configs based on the following rules:
|
|
|
|
*
|
|
|
|
* - If both internal and user-defined toolbox configs are arrays their items are merged.
|
|
|
|
* Length of the second one is kept.
|
|
|
|
*
|
|
|
|
* - If both are objects their properties are merged.
|
|
|
|
*
|
|
|
|
* - If one is an object and another is an array than internal config is replaced with user-defined
|
|
|
|
* config. This is made to allow user to override default tool's toolbox representation (single/multiple entries)
|
2021-03-31 22:29:41 +02:00
|
|
|
*/
|
2022-06-17 17:31:55 +02:00
|
|
|
public get toolbox(): ToolboxConfigEntry[] | undefined {
|
2021-03-31 22:29:41 +02:00
|
|
|
const toolToolboxSettings = this.constructable[InternalBlockToolSettings.Toolbox] as ToolboxConfig;
|
2021-04-04 14:10:26 +02:00
|
|
|
const userToolboxSettings = this.config[UserSettings.Toolbox];
|
2021-03-31 22:29:41 +02:00
|
|
|
|
|
|
|
if (_.isEmpty(toolToolboxSettings)) {
|
|
|
|
return;
|
|
|
|
}
|
2022-06-17 17:31:55 +02:00
|
|
|
if (userToolboxSettings === false) {
|
2021-03-31 22:29:41 +02:00
|
|
|
return;
|
|
|
|
}
|
2022-06-17 17:31:55 +02:00
|
|
|
/**
|
|
|
|
* Return tool's toolbox settings if user settings are not defined
|
|
|
|
*/
|
|
|
|
if (!userToolboxSettings) {
|
|
|
|
return Array.isArray(toolToolboxSettings) ? toolToolboxSettings : [ toolToolboxSettings ];
|
|
|
|
}
|
2021-03-31 22:29:41 +02:00
|
|
|
|
2022-06-17 17:31:55 +02:00
|
|
|
/**
|
|
|
|
* Otherwise merge user settings with tool's settings
|
|
|
|
*/
|
|
|
|
if (Array.isArray(toolToolboxSettings)) {
|
|
|
|
if (Array.isArray(userToolboxSettings)) {
|
|
|
|
return userToolboxSettings.map((item, i) => {
|
|
|
|
const toolToolboxEntry = toolToolboxSettings[i];
|
|
|
|
|
|
|
|
if (toolToolboxEntry) {
|
|
|
|
return {
|
|
|
|
...toolToolboxEntry,
|
|
|
|
...item,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return item;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return [ userToolboxSettings ];
|
|
|
|
} else {
|
|
|
|
if (Array.isArray(userToolboxSettings)) {
|
|
|
|
return userToolboxSettings;
|
|
|
|
}
|
|
|
|
|
|
|
|
return [
|
|
|
|
{
|
|
|
|
...toolToolboxSettings,
|
|
|
|
...userToolboxSettings,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
}
|
2021-03-31 22:29:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns Tool conversion configuration
|
|
|
|
*/
|
2023-07-20 22:27:18 +02:00
|
|
|
public get conversionConfig(): ConversionConfig | undefined {
|
2021-03-31 22:29:41 +02:00
|
|
|
return this.constructable[InternalBlockToolSettings.ConversionConfig];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns enabled inline tools for Tool
|
|
|
|
*/
|
|
|
|
public get enabledInlineTools(): boolean | string[] {
|
2021-04-08 20:17:23 +02:00
|
|
|
return this.config[UserSettings.EnabledInlineTools] || false;
|
2021-03-31 22:29:41 +02:00
|
|
|
}
|
|
|
|
|
2021-04-04 14:10:26 +02:00
|
|
|
/**
|
|
|
|
* Returns enabled tunes for Tool
|
|
|
|
*/
|
|
|
|
public get enabledBlockTunes(): boolean | string[] {
|
|
|
|
return this.config[UserSettings.EnabledBlockTunes];
|
|
|
|
}
|
|
|
|
|
2021-03-31 22:29:41 +02:00
|
|
|
/**
|
|
|
|
* Returns Tool paste configuration
|
|
|
|
*/
|
|
|
|
public get pasteConfig(): PasteConfig {
|
deps(TypeScript) - upgrade to v5, upgrade ts-loader, fix types error, fix pasteConfig getter wrapper (#2322)
* deps: upgrade typescript to v5, upgrade ts-loader to support newest TS
* Fix (??) type of `pasteConfig`
TypeScript 4.9 found something is wrong with this code, but it's unclear (to me) which line is wrong. This PR is a guess, do with it what you will.
In paste.ts there's a check to see if `pasteConfig === false`:
https://github.com/codex-team/editor.js/blob/next/src/components/modules/paste.ts#L287
However, this getter never returns false because if the LHS of the `||` is `false`, `{ }` is returned instead.
It seems like this meant to be `??` instead so that if `this.constructable[InternalBlockToolSettings.PasteConfig]` was `undefined` (missing), then `{}` would be returned instead. But maybe you meant `false` here - I don't know.
* feat: create alias for PasteConfig, fix lint
* fix: problems with types
* test: add case for disabling preventing default behavior of paste event handler, add cases for pasteConfig getter in BlockTool wrapper
* chore: upgrade CHANGELOG.md
* fix: interface naming convention
* chore: apply CHANGELOG.md suggestion
* refactor: create custom Editor instance inside test case
* fix: remove editor instance destroy after PR feedback
---------
Co-authored-by: Ryan Cavanaugh <RyanCavanaugh@users.noreply.github.com>
2023-04-02 17:52:42 +02:00
|
|
|
return this.constructable[InternalBlockToolSettings.PasteConfig] ?? {};
|
2021-03-31 22:29:41 +02:00
|
|
|
}
|
2021-04-08 20:17:23 +02:00
|
|
|
|
|
|
|
/**
|
2021-07-21 20:33:09 +02:00
|
|
|
* Returns sanitize configuration for Block Tool including configs from related Inline Tools and Block Tunes
|
2021-04-08 20:17:23 +02:00
|
|
|
*/
|
|
|
|
@_.cacheable
|
|
|
|
public get sanitizeConfig(): SanitizerConfig {
|
|
|
|
const toolRules = super.sanitizeConfig;
|
|
|
|
const baseConfig = this.baseSanitizeConfig;
|
|
|
|
|
|
|
|
if (_.isEmpty(toolRules)) {
|
|
|
|
return baseConfig;
|
|
|
|
}
|
|
|
|
|
|
|
|
const toolConfig = {} as SanitizerConfig;
|
|
|
|
|
|
|
|
for (const fieldName in toolRules) {
|
|
|
|
if (Object.prototype.hasOwnProperty.call(toolRules, fieldName)) {
|
|
|
|
const rule = toolRules[fieldName];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If rule is object, merge it with Inline Tools configuration
|
|
|
|
*
|
|
|
|
* Otherwise pass as it is
|
|
|
|
*/
|
|
|
|
if (_.isObject(rule)) {
|
|
|
|
toolConfig[fieldName] = Object.assign({}, baseConfig, rule);
|
|
|
|
} else {
|
|
|
|
toolConfig[fieldName] = rule;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return toolConfig;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns sanitizer configuration composed from sanitize config of Inline Tools enabled for Tool
|
|
|
|
*/
|
|
|
|
@_.cacheable
|
|
|
|
public get baseSanitizeConfig(): SanitizerConfig {
|
|
|
|
const baseConfig = {};
|
|
|
|
|
|
|
|
Array
|
|
|
|
.from(this.inlineTools.values())
|
|
|
|
.forEach(tool => Object.assign(baseConfig, tool.sanitizeConfig));
|
|
|
|
|
2021-07-21 20:33:09 +02:00
|
|
|
Array
|
|
|
|
.from(this.tunes.values())
|
|
|
|
.forEach(tune => Object.assign(baseConfig, tune.sanitizeConfig));
|
|
|
|
|
2021-04-08 20:17:23 +02:00
|
|
|
return baseConfig;
|
|
|
|
}
|
2021-03-31 22:29:41 +02:00
|
|
|
}
|