[BROKEN] started content-block class
This commit is contained in:
parent
adb8cb2dd1
commit
4e91649066
7 changed files with 192 additions and 15 deletions
3
src/assets/editor/text.svg.txt
Normal file
3
src/assets/editor/text.svg.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0.2 -0.3 9 11.4" width="12" height="14">
|
||||||
|
<path d="M0 2.77V.92A1 1 0 01.2.28C.35.1.56 0 .83 0h7.66c.28.01.48.1.63.28.14.17.21.38.21.64v1.85c0 .26-.08.48-.23.66-.15.17-.37.26-.66.26-.28 0-.5-.09-.64-.26a1 1 0 01-.21-.66V1.69H5.6v7.58h.5c.25 0 .45.08.6.23.17.16.25.35.25.6s-.08.45-.24.6a.87.87 0 01-.62.22H3.21a.87.87 0 01-.61-.22.78.78 0 01-.24-.6c0-.25.08-.44.24-.6a.85.85 0 01.61-.23h.5V1.7H1.73v1.08c0 .26-.08.48-.23.66-.15.17-.37.26-.66.26-.28 0-.5-.09-.64-.26A1 1 0 010 2.77z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 540 B |
|
@ -7,7 +7,7 @@ import { Component, Prop, Vue } from 'vue-property-decorator'
|
||||||
|
|
||||||
import Editor from '@editorjs/editorjs'
|
import Editor from '@editorjs/editorjs'
|
||||||
import List from '@editorjs/list'
|
import List from '@editorjs/list'
|
||||||
import { Heading, Delimiter } from '@/editor'
|
import { /* Heading, */ Delimiter, Boop } from '@/editor'
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
export default class DeckCardEditor extends Vue {
|
export default class DeckCardEditor extends Vue {
|
||||||
|
@ -26,9 +26,10 @@ export default class DeckCardEditor extends Vue {
|
||||||
holderId: this.id,
|
holderId: this.id,
|
||||||
autofocus: false,
|
autofocus: false,
|
||||||
tools: {
|
tools: {
|
||||||
header: Heading,
|
// header: Heading,
|
||||||
list: List,
|
list: { class: List, inlineToolbar: true },
|
||||||
delimiter: Delimiter
|
delimiter: { class: Delimiter, inlineToolbar: true },
|
||||||
|
boop: { class: Boop, inlineToolbar: true }
|
||||||
},
|
},
|
||||||
// data: {},
|
// data: {},
|
||||||
placeholder: 'Click here to write your card.'
|
placeholder: 'Click here to write your card.'
|
||||||
|
|
168
src/editor/content-block.ts
Normal file
168
src/editor/content-block.ts
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
import { BlockTool, BlockToolData, ToolboxConfig, API, HTMLPasteEvent, ToolConstructable, ToolSettings } from '@editorjs/editorjs'
|
||||||
|
import icon from '@/assets/editor/text.svg.txt'
|
||||||
|
|
||||||
|
interface PasteConfig {
|
||||||
|
tags: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ContentBlockConfig extends ToolSettings {
|
||||||
|
placeholder?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ContentBlockArgs {
|
||||||
|
api: API;
|
||||||
|
config?: ContentBlockConfig;
|
||||||
|
data?: BlockToolData;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CSSClasses {
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ContentBlockData extends BlockToolData {
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ContentBlock implements BlockTool {
|
||||||
|
// Default placeholder for Paragraph Tool
|
||||||
|
static get DEFAULT_PLACEHOLDER (): string {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
static _supportedTags: string[] = []
|
||||||
|
|
||||||
|
static _toolboxConfig: ToolboxConfig = {
|
||||||
|
// icon: '<svg></svg>',
|
||||||
|
icon,
|
||||||
|
title: 'UnnamedContentPlugin'
|
||||||
|
}
|
||||||
|
|
||||||
|
protected _defaultPlaceholder (): string {
|
||||||
|
return ContentBlock.DEFAULT_PLACEHOLDER
|
||||||
|
}
|
||||||
|
|
||||||
|
protected api: API
|
||||||
|
protected _element: HTMLElement
|
||||||
|
protected _data: ContentBlockData
|
||||||
|
protected _config: ContentBlockConfig
|
||||||
|
protected _placeholder: string
|
||||||
|
protected _CSS: CSSClasses
|
||||||
|
protected onKeyUp: (event: KeyboardEvent) => void
|
||||||
|
|
||||||
|
constructor ({ data, config, api }: ContentBlockArgs) {
|
||||||
|
this.api = api
|
||||||
|
this._config = config as ContentBlockConfig
|
||||||
|
|
||||||
|
this._CSS = {
|
||||||
|
block: this.api.styles.block,
|
||||||
|
wrapper: 'card-content-block'
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onKeyUp = (event: KeyboardEvent) => this._onKeyUp(event)
|
||||||
|
|
||||||
|
// Placeholder it is first Block
|
||||||
|
this._placeholder = config?.placeholder ? config.placeholder : this._defaultPlaceholder()
|
||||||
|
this._data = data as ContentBlockData
|
||||||
|
this._element = this._render()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if text content is empty and set empty string to inner html.
|
||||||
|
// We need this because some browsers (e.g. Safari) insert <br> into empty contenteditanle elements
|
||||||
|
_onKeyUp (event: KeyboardEvent) {
|
||||||
|
if (event.code !== 'Backspace' && event.code !== 'Delete') return
|
||||||
|
|
||||||
|
if (this._element.textContent === '') {
|
||||||
|
this._element.innerHTML = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// render tool view
|
||||||
|
// whenever a redraw is needed the result is saved in this._element
|
||||||
|
protected _render (): HTMLElement {
|
||||||
|
const el = document.createElement('DIV')
|
||||||
|
el.classList.add(this._CSS.wrapper, this._CSS.block)
|
||||||
|
el.dataset.placeholder = this._placeholder
|
||||||
|
el.addEventListener('keyup', this.onKeyUp)
|
||||||
|
el.innerHTML = this.data.text
|
||||||
|
el.contentEditable = 'true'
|
||||||
|
|
||||||
|
return el
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return Tool's view
|
||||||
|
public render (): HTMLElement {
|
||||||
|
return this._element
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method that specified how to merge two Text blocks.
|
||||||
|
// Called by Editor.js by backspace at the beginning of the Block
|
||||||
|
public merge (data: ContentBlockData) {
|
||||||
|
this.data = {
|
||||||
|
text: this.data.text + data.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate Paragraph block data (by default checks for emptiness)
|
||||||
|
public validate (savedData: ContentBlockData): boolean {
|
||||||
|
if (!savedData.text) return false
|
||||||
|
return savedData.text.trim() !== ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract Tool's data from the view
|
||||||
|
public save (toolsContent: HTMLElement): ContentBlockData {
|
||||||
|
return {
|
||||||
|
text: toolsContent.innerHTML
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// On paste callback fired from Editor.
|
||||||
|
public onPaste (event: HTMLPasteEvent) {
|
||||||
|
this.data = {
|
||||||
|
text: event.detail.data.innerHTML
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable Conversion Toolbar. Paragraph can be converted to/from other tools
|
||||||
|
*/
|
||||||
|
static get conversionConfig () {
|
||||||
|
return {
|
||||||
|
export: 'text', // to convert Paragraph to other block, use 'text' property of saved data
|
||||||
|
import: 'text' // to covert other block's exported string to Paragraph, fill 'text' property of tool data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanitizer rules
|
||||||
|
static get sanitize () {
|
||||||
|
return {
|
||||||
|
text: { br: true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get data (): ContentBlockData {
|
||||||
|
const text = this._element?.innerHTML
|
||||||
|
if (text !== undefined) this._data.text = text
|
||||||
|
if (this._data.text === undefined) this._data.text = ''
|
||||||
|
return this._data
|
||||||
|
}
|
||||||
|
|
||||||
|
set data (data: ContentBlockData) {
|
||||||
|
this._data = data || {}
|
||||||
|
this._element.innerHTML = this._data.text || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used by Editor.js paste handling API.
|
||||||
|
// Provides configuration to handle the tools tags.
|
||||||
|
static get pasteConfig (): PasteConfig {
|
||||||
|
return {
|
||||||
|
tags: this._supportedTags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Icon and title for displaying at the Toolbox
|
||||||
|
static get toolbox (): ToolboxConfig {
|
||||||
|
return this._toolboxConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ContentBlock as ToolConstructable
|
|
@ -1,12 +1,16 @@
|
||||||
import { BlockTool, BlockToolData, ToolConfig, ToolboxConfig, API } from '@editorjs/editorjs'
|
import { BlockTool, BlockToolData, ToolConfig, ToolboxConfig, API } from '@editorjs/editorjs'
|
||||||
|
|
||||||
|
interface BlockToolConfig extends ToolConfig {
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface BlockToolArgs {
|
export interface BlockToolArgs {
|
||||||
api: API;
|
api: API;
|
||||||
config: ToolConfig;
|
config: BlockToolConfig;
|
||||||
data?: BlockToolData;
|
data?: BlockToolData;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BlockToolExt implements BlockTool {
|
export class ContentlessBlock implements BlockTool {
|
||||||
protected api: API
|
protected api: API
|
||||||
protected _element: HTMLElement
|
protected _element: HTMLElement
|
||||||
protected _data: object
|
protected _data: object
|
||||||
|
@ -42,4 +46,4 @@ export class BlockToolExt implements BlockTool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default BlockToolExt
|
export default ContentlessBlock
|
|
@ -1,13 +1,9 @@
|
||||||
import { ToolConstructable } from '@editorjs/editorjs'
|
import { ToolConstructable } from '@editorjs/editorjs'
|
||||||
import BlockTool from './block-tool'
|
import ContentlessBlock from './contentless-block'
|
||||||
import icon from '../assets/editor/delimiter.svg.txt'
|
import icon from '../assets/editor/delimiter.svg.txt'
|
||||||
const title = 'Delimiter'
|
const title = 'Delimiter'
|
||||||
|
|
||||||
export class Delimiter extends BlockTool {
|
export class Delimiter extends ContentlessBlock {
|
||||||
static get contentless () {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
protected get _CSS () {
|
protected get _CSS () {
|
||||||
return {
|
return {
|
||||||
block: this.api.styles.block,
|
block: this.api.styles.block,
|
||||||
|
|
|
@ -9,6 +9,10 @@ import icon5 from '../assets/editor/header5.svg.txt'
|
||||||
import icon6 from '../assets/editor/header6.svg.txt'
|
import icon6 from '../assets/editor/header6.svg.txt'
|
||||||
const title = 'Heading'
|
const title = 'Heading'
|
||||||
|
|
||||||
|
interface PasteConfig {
|
||||||
|
tags: string[];
|
||||||
|
}
|
||||||
|
|
||||||
enum HeadingLevel {
|
enum HeadingLevel {
|
||||||
One = 1,
|
One = 1,
|
||||||
Two = 2,
|
Two = 2,
|
||||||
|
@ -153,7 +157,7 @@ class Heading extends BlockToolExt {
|
||||||
|
|
||||||
// Used by Editor.js paste handling API.
|
// Used by Editor.js paste handling API.
|
||||||
// Provides configuration to handle H1-H6 tags.
|
// Provides configuration to handle H1-H6 tags.
|
||||||
static get pasteConfig () {
|
static get pasteConfig (): PasteConfig {
|
||||||
return {
|
return {
|
||||||
tags: ['H1', 'H2', 'H3', 'H4', 'H5', 'H6']
|
tags: ['H1', 'H2', 'H3', 'H4', 'H5', 'H6']
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
export { default as Delimiter } from './delimiter'
|
export { default as Delimiter } from './delimiter'
|
||||||
export { default as Heading } from './heading'
|
// export { default as Heading } from './heading'
|
||||||
|
export { default as Boop } from './content-block'
|
||||||
|
|
Loading…
Add table
Reference in a new issue