mirror of
https://github.com/codex-team/editor.js
synced 2024-06-29 10:50:23 +02:00
Stub Tool (#545)
* Add stub tool * Rendered -> displayed * Bump version * font sizes updated * add opacity for selected block with stub tool * Update comment
This commit is contained in:
parent
6086886f5b
commit
866c38af2a
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -35,6 +35,10 @@
|
||||||
<symbol id="plus" viewBox="0 0 14 14">
|
<symbol id="plus" viewBox="0 0 14 14">
|
||||||
<path d="M8.05 5.8h4.625a1.125 1.125 0 0 1 0 2.25H8.05v4.625a1.125 1.125 0 0 1-2.25 0V8.05H1.125a1.125 1.125 0 0 1 0-2.25H5.8V1.125a1.125 1.125 0 0 1 2.25 0V5.8z"/>
|
<path d="M8.05 5.8h4.625a1.125 1.125 0 0 1 0 2.25H8.05v4.625a1.125 1.125 0 0 1-2.25 0V8.05H1.125a1.125 1.125 0 0 1 0-2.25H5.8V1.125a1.125 1.125 0 0 1 2.25 0V5.8z"/>
|
||||||
|
|
||||||
|
</symbol>
|
||||||
|
<symbol id="sad-face" viewBox="0 0 52 52">
|
||||||
|
<path fill="#D76B6B" fill-rule="nonzero" d="M26 52C11.64 52 0 40.36 0 26S11.64 0 26 0s26 11.64 26 26-11.64 26-26 26zm0-3.25c12.564 0 22.75-10.186 22.75-22.75S38.564 3.25 26 3.25 3.25 13.436 3.25 26 13.436 48.75 26 48.75zM15.708 33.042a2.167 2.167 0 1 1 0-4.334 2.167 2.167 0 0 1 0 4.334zm23.834 0a2.167 2.167 0 1 1 0-4.334 2.167 2.167 0 0 1 0 4.334zm-15.875 5.452a1.083 1.083 0 1 1-1.834-1.155c1.331-2.114 3.49-3.179 6.334-3.179 2.844 0 5.002 1.065 6.333 3.18a1.083 1.083 0 1 1-1.833 1.154c-.913-1.45-2.366-2.167-4.5-2.167s-3.587.717-4.5 2.167z"/>
|
||||||
|
|
||||||
</symbol>
|
</symbol>
|
||||||
<symbol id="unlink" viewBox="0 0 16 18">
|
<symbol id="unlink" viewBox="0 0 16 18">
|
||||||
<path transform="rotate(-45 8.358 11.636)" d="M9.14 9.433c.008-.12-.087-.686-.112-.81a1.4 1.4 0 0 0-1.64-1.106l-3.977.772a1.4 1.4 0 0 0 .535 2.749l.935-.162s.019 1.093.592 2.223l-1.098.148A3.65 3.65 0 1 1 2.982 6.08l3.976-.773c1.979-.385 3.838.919 4.28 2.886.51 2.276-1.084 2.816-1.073 2.935.011.12-.394-1.59-1.026-1.696zm3.563-.875l2.105 3.439a3.65 3.65 0 0 1-6.19 3.868L6.47 12.431c-1.068-1.71-.964-2.295-.49-3.07.067-.107 1.16-1.466 1.48-.936-.12.036.9 1.33.789 1.398-.656.41-.28.76.13 1.415l2.145 3.435a1.4 1.4 0 0 0 2.375-1.484l-1.132-1.941c.42-.435 1.237-1.054.935-2.69zm1.88-2.256h3.4a1.125 1.125 0 0 1 0 2.25h-3.4a1.125 1.125 0 0 1 0-2.25zM11.849.038c.62 0 1.125.503 1.125 1.125v3.4a1.125 1.125 0 0 1-2.25 0v-3.4c0-.622.503-1.125 1.125-1.125z"/>
|
<path transform="rotate(-45 8.358 11.636)" d="M9.14 9.433c.008-.12-.087-.686-.112-.81a1.4 1.4 0 0 0-1.64-1.106l-3.977.772a1.4 1.4 0 0 0 .535 2.749l.935-.162s.019 1.093.592 2.223l-1.098.148A3.65 3.65 0 1 1 2.982 6.08l3.976-.773c1.979-.385 3.838.919 4.28 2.886.51 2.276-1.084 2.816-1.073 2.935.011.12-.394-1.59-1.026-1.696zm3.563-.875l2.105 3.439a3.65 3.65 0 0 1-6.19 3.868L6.47 12.431c-1.068-1.71-.964-2.295-.49-3.07.067-.107 1.16-1.466 1.48-.936-.12.036.9 1.33.789 1.398-.656.41-.28.76.13 1.415l2.145 3.435a1.4 1.4 0 0 0 2.375-1.484l-1.132-1.941c.42-.435 1.237-1.054.935-2.69zm1.88-2.256h3.4a1.125 1.125 0 0 1 0 2.25h-3.4a1.125 1.125 0 0 1 0-2.25zM11.849.038c.62 0 1.125.503 1.125 1.125v3.4a1.125 1.125 0 0 1-2.25 0v-3.4c0-.622.503-1.125 1.125-1.125z"/>
|
||||||
|
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 4.4 KiB |
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "codex.editor",
|
"name": "codex.editor",
|
||||||
"version": "2.7.0",
|
"version": "2.7.1",
|
||||||
"description": "Codex Editor. Native JS, based on API and Open Source",
|
"description": "Codex Editor. Native JS, based on API and Open Source",
|
||||||
"main": "build/codex-editor.js",
|
"main": "build/codex-editor.js",
|
||||||
"types": "./types/index.d.ts",
|
"types": "./types/index.d.ts",
|
||||||
|
|
3
src/assets/sad-face.svg
Normal file
3
src/assets/sad-face.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 52 52">
|
||||||
|
<path fill="#D76B6B" fill-rule="nonzero" d="M26 52C11.64 52 0 40.36 0 26S11.64 0 26 0s26 11.64 26 26-11.64 26-26 26zm0-3.25c12.564 0 22.75-10.186 22.75-22.75S38.564 3.25 26 3.25 3.25 13.436 3.25 26 13.436 48.75 26 48.75zM15.708 33.042a2.167 2.167 0 1 1 0-4.334 2.167 2.167 0 0 1 0 4.334zm23.834 0a2.167 2.167 0 1 1 0-4.334 2.167 2.167 0 0 1 0 4.334zm-15.875 5.452a1.083 1.083 0 1 1-1.834-1.155c1.331-2.114 3.49-3.179 6.334-3.179 2.844 0 5.002 1.065 6.333 3.18a1.083 1.083 0 1 1-1.833 1.154c-.913-1.45-2.366-2.167-4.5-2.167s-3.587.717-4.5 2.167z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 643 B |
|
@ -1,6 +1,7 @@
|
||||||
import Module from '../__module';
|
import Module from '../__module';
|
||||||
import _, {ChainData} from '../utils';
|
import _, {ChainData} from '../utils';
|
||||||
import {BlockToolData} from '../../../types';
|
import {BlockToolData} from '../../../types';
|
||||||
|
import {BlockToolConstructable} from '../../../types/tools';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Codex Editor Renderer Module
|
* Codex Editor Renderer Module
|
||||||
|
@ -57,23 +58,40 @@ export default class Renderer extends Module {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
public async insertBlock(item): Promise<void> {
|
public async insertBlock(item): Promise<void> {
|
||||||
|
const { Tools, BlockManager } = this.Editor;
|
||||||
const tool = item.type;
|
const tool = item.type;
|
||||||
const data = item.data;
|
const data = item.data;
|
||||||
const settings = item.settings;
|
const settings = item.settings;
|
||||||
|
|
||||||
if (tool in this.Editor.Tools.available) {
|
if (tool in Tools.available) {
|
||||||
try {
|
try {
|
||||||
this.Editor.BlockManager.insert(tool, data, settings);
|
BlockManager.insert(tool, data, settings);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
_.log(`Block «${tool}» skipped because of plugins error`, 'warn', data);
|
_.log(`Block «${tool}» skipped because of plugins error`, 'warn', data);
|
||||||
throw Error(error);
|
throw Error(error);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/**
|
|
||||||
* @todo show warning notification message
|
/** If Tool is unavailable, create stub Block for it */
|
||||||
*
|
const stubData = {
|
||||||
* `${tool} blocks was skipped.`
|
savedData: {
|
||||||
*/
|
type: tool,
|
||||||
|
data,
|
||||||
|
},
|
||||||
|
title: tool,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (tool in Tools.unavailable) {
|
||||||
|
const toolToolboxSettings = (Tools.unavailable[tool] as BlockToolConstructable).toolbox;
|
||||||
|
const userToolboxSettings = Tools.getToolSettings(tool).toolbox;
|
||||||
|
|
||||||
|
stubData.title = toolToolboxSettings.title || userToolboxSettings.title || stubData.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
const stub = BlockManager.insert(Tools.stubTool, stubData, settings);
|
||||||
|
|
||||||
|
stub.stretched = true;
|
||||||
|
|
||||||
_.log(`Tool «${tool}» is not found. Check 'tools' property at your initial CodeX Editor config.`, 'warn');
|
_.log(`Tool «${tool}» is not found. Check 'tools' property at your initial CodeX Editor config.`, 'warn');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
import Module from '../__module';
|
import Module from '../__module';
|
||||||
import {OutputData} from '../../../types';
|
import {OutputData} from '../../../types';
|
||||||
|
import Block from '../block';
|
||||||
|
|
||||||
declare const VERSION: string;
|
declare const VERSION: string;
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ export default class Saver extends Module {
|
||||||
const blocks = this.Editor.BlockManager.blocks,
|
const blocks = this.Editor.BlockManager.blocks,
|
||||||
chainData = [];
|
chainData = [];
|
||||||
|
|
||||||
blocks.forEach((block) => {
|
blocks.forEach((block: Block) => {
|
||||||
chainData.push(block.save());
|
chainData.push(block.save());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -51,6 +52,13 @@ export default class Saver extends Module {
|
||||||
/** Group process info */
|
/** Group process info */
|
||||||
console.log(`«${extraction.tool}» saving info`, extraction);
|
console.log(`«${extraction.tool}» saving info`, extraction);
|
||||||
totalTime += extraction.time;
|
totalTime += extraction.time;
|
||||||
|
|
||||||
|
/** If it was stub Block, get original data */
|
||||||
|
if (extraction.tool === this.Editor.Tools.stubTool) {
|
||||||
|
blocks.push(extraction.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
blocks.push({
|
blocks.push({
|
||||||
type: extraction.tool,
|
type: extraction.tool,
|
||||||
data: extraction.data,
|
data: extraction.data,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {BlockToolConstructable, ToolConfig, ToolConstructable, ToolSettings} fro
|
||||||
import BoldInlineTool from '../inline-tools/inline-tool-bold';
|
import BoldInlineTool from '../inline-tools/inline-tool-bold';
|
||||||
import ItalicInlineTool from '../inline-tools/inline-tool-italic';
|
import ItalicInlineTool from '../inline-tools/inline-tool-italic';
|
||||||
import LinkInlineTool from '../inline-tools/inline-tool-link';
|
import LinkInlineTool from '../inline-tools/inline-tool-link';
|
||||||
|
import Stub from '../tools/stub';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module Codex Editor Tools Submodule
|
* @module Codex Editor Tools Submodule
|
||||||
|
@ -24,6 +25,13 @@ import LinkInlineTool from '../inline-tools/inline-tool-link';
|
||||||
*/
|
*/
|
||||||
export default class Tools extends Module {
|
export default class Tools extends Module {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of Stub Tool
|
||||||
|
* Stub Tool is used to substitute unavailable block Tools and store their data
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
public stubTool = 'stub';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns available Tools
|
* Returns available Tools
|
||||||
* @return {Tool[]}
|
* @return {Tool[]}
|
||||||
|
@ -384,6 +392,7 @@ export default class Tools extends Module {
|
||||||
class: Paragraph,
|
class: Paragraph,
|
||||||
inlineToolbar: true,
|
inlineToolbar: true,
|
||||||
},
|
},
|
||||||
|
stub: Stub,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
84
src/components/tools/stub/index.ts
Normal file
84
src/components/tools/stub/index.ts
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
import $ from '../../dom';
|
||||||
|
import {BlockTool, BlockToolData} from '../../../../types';
|
||||||
|
|
||||||
|
export default class Stub implements BlockTool {
|
||||||
|
/**
|
||||||
|
* Stub styles
|
||||||
|
* @type {{wrapper: string; info: string; title: string; subtitle: string}}
|
||||||
|
*/
|
||||||
|
private CSS = {
|
||||||
|
wrapper: 'ce-stub',
|
||||||
|
info: 'ce-stub__info',
|
||||||
|
title: 'ce-stub__title',
|
||||||
|
subtitle: 'ce-stub__subtitle',
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main stub wrapper
|
||||||
|
*/
|
||||||
|
private readonly wrapper: HTMLElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stub title — tool name
|
||||||
|
*/
|
||||||
|
private readonly title: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stub hint
|
||||||
|
*/
|
||||||
|
private readonly subtitle: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Original Tool data
|
||||||
|
*/
|
||||||
|
private readonly savedData: BlockToolData;
|
||||||
|
|
||||||
|
constructor({data, config, api}) {
|
||||||
|
this.title = data.title || 'Error';
|
||||||
|
this.subtitle = 'The block can not be displayed correctly.';
|
||||||
|
this.savedData = data.savedData;
|
||||||
|
|
||||||
|
this.wrapper = this.make();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns stub holder
|
||||||
|
* @return {HTMLElement}
|
||||||
|
*/
|
||||||
|
public render(): HTMLElement {
|
||||||
|
return this.wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return original Tool data
|
||||||
|
* @return {BlockToolData}
|
||||||
|
*/
|
||||||
|
public save(): BlockToolData {
|
||||||
|
return this.savedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Tool html markup
|
||||||
|
* @return {HTMLElement}
|
||||||
|
*/
|
||||||
|
private make(): HTMLElement {
|
||||||
|
const wrapper = $.make('div', this.CSS.wrapper);
|
||||||
|
const icon = $.svg('sad-face', 52, 52);
|
||||||
|
const infoContainer = $.make('div', this.CSS.info);
|
||||||
|
const title = $.make('div', this.CSS.title, {
|
||||||
|
textContent: this.title,
|
||||||
|
});
|
||||||
|
const subtitle = $.make('div', this.CSS.subtitle, {
|
||||||
|
textContent: this.subtitle,
|
||||||
|
});
|
||||||
|
|
||||||
|
wrapper.appendChild(icon);
|
||||||
|
|
||||||
|
infoContainer.appendChild(title);
|
||||||
|
infoContainer.appendChild(subtitle);
|
||||||
|
|
||||||
|
wrapper.appendChild(infoContainer);
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,8 @@
|
||||||
animation: selectionBounce 0.2s 1;
|
animation: selectionBounce 0.2s 1;
|
||||||
animation-fill-mode: forwards;
|
animation-fill-mode: forwards;
|
||||||
|
|
||||||
img {
|
img,
|
||||||
|
.ce-stub {
|
||||||
opacity: 0.55;
|
opacity: 0.55;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,3 +7,4 @@
|
||||||
@import url('block.css');
|
@import url('block.css');
|
||||||
@import url('animations.css');
|
@import url('animations.css');
|
||||||
@import url('export.css');
|
@import url('export.css');
|
||||||
|
@import url('stub.css');
|
||||||
|
|
26
src/styles/stub.css
Normal file
26
src/styles/stub.css
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
.ce-stub {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
padding: 3.5em 0;
|
||||||
|
margin: 17px 0;
|
||||||
|
border-radius: 3px;
|
||||||
|
background: #fcf7f7;
|
||||||
|
color: #b46262;
|
||||||
|
|
||||||
|
&__info {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
margin-bottom: 3px;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 18px;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__subtitle {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
12
types/tools/block-tool.d.ts
vendored
12
types/tools/block-tool.d.ts
vendored
|
@ -14,11 +14,6 @@ export interface BlockTool extends Tool {
|
||||||
*/
|
*/
|
||||||
sanitize?: SanitizerConfig;
|
sanitize?: SanitizerConfig;
|
||||||
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
constructor: BlockToolConstructable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return Tool's main block-wrapper
|
* Return Tool's main block-wrapper
|
||||||
* @return {HTMLElement}
|
* @return {HTMLElement}
|
||||||
|
@ -74,12 +69,7 @@ export interface BlockToolConstructable extends ToolConstructable {
|
||||||
/**
|
/**
|
||||||
* Paste substitutions configuration
|
* Paste substitutions configuration
|
||||||
*/
|
*/
|
||||||
onPaste?: PasteConfig;
|
pasteConfig?: PasteConfig;
|
||||||
|
|
||||||
/**
|
|
||||||
* Paste substitutions configuration
|
|
||||||
*/
|
|
||||||
pasteConfig: PasteConfig;
|
|
||||||
|
|
||||||
new (config: {api: API, config: ToolConfig, data: BlockToolData}): BlockTool;
|
new (config: {api: API, config: ToolConfig, data: BlockToolData}): BlockTool;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue