removes obsolete editor component
This commit is contained in:
parent
136da9d694
commit
cadb759fba
2 changed files with 0 additions and 255 deletions
|
@ -1,5 +1,4 @@
|
||||||
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 List } from './list'
|
|
||||||
export { default as Charges } from './charges'
|
export { default as Charges } from './charges'
|
||||||
export { default as DnDStats } from './dnd-stats'
|
export { default as DnDStats } from './dnd-stats'
|
||||||
|
|
|
@ -1,254 +0,0 @@
|
||||||
import {
|
|
||||||
ContentBlock,
|
|
||||||
ContentBlockArgs,
|
|
||||||
ContentBlockConfig,
|
|
||||||
ContentBlockData,
|
|
||||||
ConversionConfig
|
|
||||||
} from './content-block'
|
|
||||||
|
|
||||||
import icon from '../assets/editor/list.svg.txt'
|
|
||||||
import iconUL from '../assets/editor/list_unordered.svg.txt'
|
|
||||||
import iconOL from '../assets/editor/list_ordered.svg.txt'
|
|
||||||
|
|
||||||
const title = 'List'
|
|
||||||
|
|
||||||
enum ListStyle {
|
|
||||||
Ordered = 'OL',
|
|
||||||
Unordered = 'UL'
|
|
||||||
}
|
|
||||||
const icons = {
|
|
||||||
[ListStyle.Ordered]: iconOL,
|
|
||||||
[ListStyle.Unordered]: iconUL
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ListConfig extends ContentBlockConfig {
|
|
||||||
placeholder?: string;
|
|
||||||
styles: ListStyle[];
|
|
||||||
defaultStyle: ListStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ListData extends ContentBlockData {
|
|
||||||
style: ListStyle;
|
|
||||||
items: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ListConversionConfig extends ConversionConfig {
|
|
||||||
import: (str: string) => ListData;
|
|
||||||
export: (data: ListData) => string;
|
|
||||||
}
|
|
||||||
|
|
||||||
class List extends ContentBlock {
|
|
||||||
static _supportedTags = ['UL', 'OL', 'LI']
|
|
||||||
static _toolboxConfig = { icon, title }
|
|
||||||
|
|
||||||
protected _config: ListConfig
|
|
||||||
private defaultStyle: ListStyle
|
|
||||||
private currentStyle: ListStyle
|
|
||||||
|
|
||||||
constructor (args: ContentBlockArgs) {
|
|
||||||
super(args)
|
|
||||||
this._config = args.config as ListConfig
|
|
||||||
|
|
||||||
if (this._config.styles === undefined) {
|
|
||||||
this._config.styles = [ListStyle.Unordered, ListStyle.Ordered]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._config.defaultStyle === undefined) {
|
|
||||||
this._config.defaultStyle = ListStyle.Unordered
|
|
||||||
}
|
|
||||||
if (this._config.styles.indexOf(this._config.defaultStyle) === -1) {
|
|
||||||
console.warn('(ง\'̀-\'́)ง List Tool: the default style specified was not found in available styles')
|
|
||||||
}
|
|
||||||
this.defaultStyle = this._config.defaultStyle
|
|
||||||
this.currentStyle = this.defaultStyle
|
|
||||||
|
|
||||||
this.data = {
|
|
||||||
style: this.currentStyle,
|
|
||||||
items: (args.data as ListData).items
|
|
||||||
}
|
|
||||||
|
|
||||||
this._settingButtons = this._config.styles.map(listStyle => {
|
|
||||||
return {
|
|
||||||
name: listStyle,
|
|
||||||
icon: icons[listStyle] || icon,
|
|
||||||
action: (name: string) => this.setStyle(name as ListStyle),
|
|
||||||
isActive: (name: string): boolean => name === this.currentStyle
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public get data (): ListData {
|
|
||||||
// first render
|
|
||||||
if (!this._element) return this._data as ListData
|
|
||||||
|
|
||||||
const items = this.queryItems()
|
|
||||||
const data = this._data as ListData
|
|
||||||
data.items = Array.from(items).map(item => item.innerText)
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
public set data (data: ListData) {
|
|
||||||
const currentData = this._data as ListData
|
|
||||||
|
|
||||||
if (data.style === undefined) data.style = currentData.style || this.defaultStyle
|
|
||||||
if (data.items === undefined) data.items = currentData.items || []
|
|
||||||
|
|
||||||
this._data = data
|
|
||||||
this.currentStyle = data.style
|
|
||||||
|
|
||||||
const newList = this._render()
|
|
||||||
if (this._element.parentNode) {
|
|
||||||
this._element.parentNode.replaceChild(newList, this._element)
|
|
||||||
}
|
|
||||||
this._element = newList
|
|
||||||
}
|
|
||||||
|
|
||||||
private setStyle (style: ListStyle) {
|
|
||||||
this.data = { style, items: this.data.items || [] }
|
|
||||||
}
|
|
||||||
|
|
||||||
protected _render (): HTMLElement {
|
|
||||||
const el = document.createElement(this.currentStyle)
|
|
||||||
el.classList.add('cdx-list', this._CSS.block)
|
|
||||||
el.contentEditable = 'true'
|
|
||||||
el.dataset.placeholder = this._config.placeholder || ''
|
|
||||||
|
|
||||||
const items = this.data.items
|
|
||||||
|
|
||||||
if (!items || !items.length) {
|
|
||||||
const li = document.createElement('LI')
|
|
||||||
li.innerText = ''
|
|
||||||
li.classList.add('cdx-list__item')
|
|
||||||
el.appendChild(li)
|
|
||||||
} else {
|
|
||||||
items.forEach(item => {
|
|
||||||
const li = document.createElement('LI')
|
|
||||||
li.innerText = item
|
|
||||||
li.classList.add('cdx-list__item')
|
|
||||||
el.appendChild(li)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
el.addEventListener('keydown', event => {
|
|
||||||
// on pressing Enter
|
|
||||||
if (event.keyCode === 13) return this.getOutOfList(event)
|
|
||||||
// on pressing Backspace
|
|
||||||
if (event.keyCode === 8) return this.backspace(event)
|
|
||||||
}, false)
|
|
||||||
|
|
||||||
return el
|
|
||||||
}
|
|
||||||
|
|
||||||
private queryItems (): NodeListOf<HTMLLIElement> {
|
|
||||||
return this._element.querySelectorAll('.cdx-list__item')
|
|
||||||
}
|
|
||||||
|
|
||||||
private get currentItem (): Element | undefined {
|
|
||||||
const selection = window.getSelection()
|
|
||||||
if (selection === null) return
|
|
||||||
|
|
||||||
let currentNode = selection.anchorNode
|
|
||||||
if (currentNode === null) return
|
|
||||||
|
|
||||||
if (currentNode.nodeType !== Node.ELEMENT_NODE) {
|
|
||||||
currentNode = currentNode.parentNode
|
|
||||||
}
|
|
||||||
|
|
||||||
return (currentNode as HTMLElement).closest('.cdx-list__item') || undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
// leave list by pressing enter on an empty list item
|
|
||||||
private getOutOfList (event: KeyboardEvent) {
|
|
||||||
const items = this.queryItems()
|
|
||||||
if (items.length < 2) return
|
|
||||||
|
|
||||||
const lastItem = items[items.length - 1]
|
|
||||||
const currentItem = this.currentItem
|
|
||||||
|
|
||||||
// prevent generation of new li if last li is empty
|
|
||||||
if (currentItem === lastItem && !lastItem.innerText.trim().length) {
|
|
||||||
if (!currentItem.parentElement) return // somethings really wrong
|
|
||||||
currentItem.parentElement.removeChild(currentItem)
|
|
||||||
this.api.blocks.insertNewBlock()
|
|
||||||
event.preventDefault()
|
|
||||||
event.stopPropagation()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public backspace (event: KeyboardEvent) {
|
|
||||||
const items = this.queryItems()
|
|
||||||
const firstItem = items[0]
|
|
||||||
|
|
||||||
if (firstItem === undefined) return
|
|
||||||
if (items.length < 2 && !firstItem.innerText.trim()) event.preventDefault()
|
|
||||||
}
|
|
||||||
|
|
||||||
public selectItem (event: KeyboardEvent) {
|
|
||||||
event.preventDefault()
|
|
||||||
|
|
||||||
const selection = window.getSelection()
|
|
||||||
if (selection === null) return // no selection, no problem
|
|
||||||
|
|
||||||
const currentNode = selection.anchorNode?.parentNode
|
|
||||||
if (currentNode === null) return
|
|
||||||
|
|
||||||
const currentItem = (currentNode as Element).closest('.cdx-list__item')
|
|
||||||
if (currentItem === null) return
|
|
||||||
|
|
||||||
const range = new Range()
|
|
||||||
|
|
||||||
range.selectNodeContents(currentItem)
|
|
||||||
selection.removeAllRanges()
|
|
||||||
selection.addRange(range)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected pasteHandler (element: HTMLUListElement | HTMLOListElement | HTMLLIElement): ListData {
|
|
||||||
const tag = element.tagName
|
|
||||||
const style = tag === ListStyle.Ordered ? ListStyle.Ordered : ListStyle.Unordered
|
|
||||||
const data: ListData = { style, items: [] }
|
|
||||||
|
|
||||||
if (tag === 'LI') { // does this really happen?
|
|
||||||
data.items.push(element.innerText)
|
|
||||||
} else {
|
|
||||||
const items = Array.from(element.querySelectorAll('LI'))
|
|
||||||
data.items = items.map(item => (item as HTMLElement).innerText).filter(item => !!item.trim())
|
|
||||||
}
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
// allow to use native enter behavior
|
|
||||||
static get enableLineBreaks (): boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
static get sanitize () {
|
|
||||||
return {
|
|
||||||
style: {},
|
|
||||||
items: {
|
|
||||||
br: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static get conversionConfig (): ListConversionConfig {
|
|
||||||
return {
|
|
||||||
export: data => {
|
|
||||||
return data.items.join(' * ')
|
|
||||||
},
|
|
||||||
import: str => {
|
|
||||||
return {
|
|
||||||
items: [str],
|
|
||||||
style: ListStyle.Unordered
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public save (): ListData {
|
|
||||||
console.log('saving list', this.data)
|
|
||||||
return this.data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default List
|
|
Loading…
Add table
Reference in a new issue