[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 List from '@editorjs/list'
|
||||
import { Heading, Delimiter } from '@/editor'
|
||||
import { /* Heading, */ Delimiter, Boop } from '@/editor'
|
||||
|
||||
@Component
|
||||
export default class DeckCardEditor extends Vue {
|
||||
|
@ -26,9 +26,10 @@ export default class DeckCardEditor extends Vue {
|
|||
holderId: this.id,
|
||||
autofocus: false,
|
||||
tools: {
|
||||
header: Heading,
|
||||
list: List,
|
||||
delimiter: Delimiter
|
||||
// header: Heading,
|
||||
list: { class: List, inlineToolbar: true },
|
||||
delimiter: { class: Delimiter, inlineToolbar: true },
|
||||
boop: { class: Boop, inlineToolbar: true }
|
||||
},
|
||||
// data: {},
|
||||
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'
|
||||
|
||||
interface BlockToolConfig extends ToolConfig {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export interface BlockToolArgs {
|
||||
api: API;
|
||||
config: ToolConfig;
|
||||
config: BlockToolConfig;
|
||||
data?: BlockToolData;
|
||||
}
|
||||
|
||||
export class BlockToolExt implements BlockTool {
|
||||
export class ContentlessBlock implements BlockTool {
|
||||
protected api: API
|
||||
protected _element: HTMLElement
|
||||
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 BlockTool from './block-tool'
|
||||
import ContentlessBlock from './contentless-block'
|
||||
import icon from '../assets/editor/delimiter.svg.txt'
|
||||
const title = 'Delimiter'
|
||||
|
||||
export class Delimiter extends BlockTool {
|
||||
static get contentless () {
|
||||
return true
|
||||
}
|
||||
|
||||
export class Delimiter extends ContentlessBlock {
|
||||
protected get _CSS () {
|
||||
return {
|
||||
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'
|
||||
const title = 'Heading'
|
||||
|
||||
interface PasteConfig {
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
enum HeadingLevel {
|
||||
One = 1,
|
||||
Two = 2,
|
||||
|
@ -153,7 +157,7 @@ class Heading extends BlockToolExt {
|
|||
|
||||
// Used by Editor.js paste handling API.
|
||||
// Provides configuration to handle H1-H6 tags.
|
||||
static get pasteConfig () {
|
||||
static get pasteConfig (): PasteConfig {
|
||||
return {
|
||||
tags: ['H1', 'H2', 'H3', 'H4', 'H5', 'H6']
|
||||
}
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
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