@ebl-vue/editor-full 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +187 -181
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/Editor/Editor.vue +36 -19
- package/src/index.ts +8 -2
- package/types/index.d.ts +5 -1
- package/types/plugins/index.d.ts +0 -0
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/constants/index.ts","../src/utils/install.ts","../src/plugins/drag-drop/index.ts","../src/icons/index.ts","../src/plugins/header/H1.ts","../src/plugins/header/H2.ts","../src/plugins/header/H3.ts","../src/plugins/header/H4.ts","../src/plugins/header/H5.ts","../src/plugins/header/H6.ts","../src/plugins/block-alignment/index.ts","../src/plugins/paragraph/index.ts","../src/plugins/paragraph/utils/makeFragment.ts","../src/plugins/code/index.ts","../src/plugins/code/utils/string.ts","../src/plugins/quote/index.ts","../src/plugins/delimiter/index.ts","../src/plugins/list/styles/CssPrefix.ts","../src/plugins/list/ListRenderer/ListRenderer.ts","../src/plugins/list/ListRenderer/OrderedListRenderer.ts","../src/plugins/list/ListRenderer/UnorderedListRenderer.ts","../src/plugins/list/utils/type-guards.ts","../src/plugins/list/ListRenderer/ChecklistRenderer.ts","../src/plugins/list/utils/getSiblings.ts","../src/plugins/list/utils/getChildItems.ts","../src/plugins/list/utils/getItemChildWrapper.ts","../src/plugins/list/utils/removeChildWrapperIfEmpty.ts","../src/plugins/list/utils/getItemContentElement.ts","../src/plugins/list/utils/focusItem.ts","../src/plugins/list/ListTabulator/index.ts","../src/plugins/list/utils/isLastItem.ts","../src/plugins/list/utils/itemHasSublist.ts","../src/plugins/list/types/OlCounterType.ts","../src/plugins/list/index.ts","../src/plugins/list/utils/normalizeData.ts","../src/plugins/undo/observer.ts","../src/plugins/undo/index.ts","../src/plugins/alert/index.ts","../src/plugins/indent/index.ts","../src/plugins/marker/index.ts","../src/plugins/color-picker/index.ts","../src/plugins/underline/index.ts","../src/plugins/inline-code/index.ts","../src/plugins/table/utils/dom.ts","../src/plugins/table/utils/popover.ts","../src/plugins/table/toolbox.ts","../src/plugins/table/table.ts","../src/plugins/table/utils/throttled.ts","../src/plugins/table/plugin.ts","../src/plugins/imageTool/utils/dom.ts","../src/plugins/imageTool/ui.ts","../src/plugins/imageTool/uploader.ts","../src/plugins/imageTool/utils/index.ts","../src/plugins/imageTool/index.ts","../src/plugins/imageResizeCrop/ImageTune.ts","../src/components/Editor/Editor.vue","../src/components/index.ts","../src/i18n/zh-cn.ts","../src/index.ts","../src/installer.ts"],"sourcesContent":["export const INSTALLED_KEY = Symbol('INSTALLED_KEY')\r\n","import type { SFCWithInstall } from 'types'\r\nimport type {App} from 'vue'\r\nexport const withInstall = <T, E extends Record<string, any>>(\r\n main: T,\r\n extra?: E\r\n) => {\r\n ;(main as SFCWithInstall<T>).install = (app:App): void => {\r\n for (const comp of [main, ...Object.values(extra ?? {})]) {\r\n app.component(comp.name, comp)\r\n }\r\n }\r\n\r\n if (extra) {\r\n for (const [key, comp] of Object.entries(extra)) {\r\n ;(main as any)[key] = comp\r\n }\r\n }\r\n return main as SFCWithInstall<T> & E\r\n}","import './index.css';\r\n\r\nimport type EditorJS from '@ebl-vue/editorjs/types';\r\n\r\nexport default class DragDrop {\r\n private toolbar: any;\r\n private borderStyle: string;\r\n private api: any;\r\n private holder: HTMLElement;\r\n private readOnly: boolean | undefined;\r\n private startBlock: number | null;\r\n private endBlock: number | null;\r\n\r\n constructor(\r\n holderId: string,\r\n readonly: boolean,\r\n editor: EditorJS, \r\n borderStyle: string) {\r\n const {\r\n blocks,\r\n toolbar,\r\n } = editor;\r\n this.toolbar = toolbar;\r\n this.borderStyle = borderStyle || '1px dashed #aaa';\r\n this.api = blocks;\r\n this.holder = document.getElementById(holderId) as HTMLElement;\r\n this.readOnly =readonly;\r\n this.startBlock = null;\r\n this.endBlock = null;\r\n\r\n\r\n this.setDragListener();\r\n this.setDropListener();\r\n }\r\n\r\n\r\n setElementCursor(element: HTMLElement|null) {\r\n if (!element) return;\r\n const range = document.createRange();\r\n const selection = window.getSelection();\r\n\r\n range.setStart(element.childNodes[0], 0);\r\n range.collapse(true);\r\n selection?.removeAllRanges();\r\n selection?.addRange(range);\r\n element.focus();\r\n }\r\n\r\n\r\n setDragListener() {\r\n if (!this.readOnly) {\r\n const settingsButton = this.holder?.querySelector<HTMLElement>('.ce-toolbar__settings-btn');\r\n if (settingsButton) {\r\n this.initializeDragListener(settingsButton);\r\n } else {\r\n const observer = new MutationObserver((mutations, obs) => {\r\n const settingsButton = this.holder?.querySelector<HTMLElement>(\r\n \".ce-toolbar__settings-btn\"\r\n );\r\n if (settingsButton) {\r\n this.initializeDragListener(settingsButton);\r\n obs.disconnect();\r\n }\r\n });\r\n\r\n observer.observe(this.holder, {\r\n childList: true,\r\n subtree: true,\r\n });\r\n }\r\n }\r\n }\r\n\r\n initializeDragListener(settingsButton: HTMLElement) {\r\n settingsButton.setAttribute(\"draggable\", \"true\");\r\n settingsButton.addEventListener(\"dragstart\", () => {\r\n this.startBlock = this.api.getCurrentBlockIndex();\r\n });\r\n settingsButton.addEventListener('drag', () => {\r\n this.toolbar.close(); \r\n if (!this.isTheOnlyBlock()) {\r\n const allBlocks = this.holder.querySelectorAll('.ce-block') as NodeListOf<HTMLElement>;\r\n const blockFocused = this.holder.querySelector<HTMLElement>('.ce-block--drop-target');\r\n this.setElementCursor(blockFocused);\r\n this.setBorderBlocks(allBlocks, blockFocused);\r\n }\r\n });\r\n }\r\n \r\n\r\n\r\n setBorderBlocks(allBlocks: NodeListOf<HTMLElement>, blockFocused: HTMLElement|null) {\r\n Object.values(allBlocks).forEach((block: HTMLElement) => {\r\n const blockContent = block.querySelector<HTMLElement>('.ce-block__content');\r\n if (block !== blockFocused) {\r\n blockContent?.style.removeProperty('border-top');\r\n blockContent?.style.removeProperty('border-bottom');\r\n } else {\r\n const index = Object.keys(allBlocks).find((key) => allBlocks[Number(key)] === blockFocused);\r\n if (index && Number(index) > this.startBlock!) blockContent!.style.borderBottom = this.borderStyle;\r\n else blockContent!.style.borderTop = this.borderStyle;\r\n }\r\n });\r\n }\r\n\r\n\r\n setDropListener() {\r\n document.addEventListener('drop', (event: DragEvent) => {\r\n const { target } = event;\r\n if (this.holder.contains(target as HTMLElement) && this.startBlock !== null) {\r\n const dropTarget = this.getDropTarget(target as HTMLElement);\r\n if (dropTarget) {\r\n const blockContent = dropTarget.querySelector<HTMLElement>('.ce-block__content');\r\n blockContent?.style.removeProperty('border-top');\r\n blockContent?.style.removeProperty('border-bottom');\r\n this.endBlock = this.getTargetPosition(dropTarget as HTMLElement);\r\n this.moveBlocks();\r\n }\r\n }\r\n this.startBlock = null;\r\n });\r\n }\r\n\r\n \r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n \r\n getDropTarget(target: HTMLElement) {\r\n return target.classList.contains('ce-block')\r\n ? target\r\n : target.closest('.ce-block');\r\n }\r\n\r\n\r\n getTargetPosition(target: HTMLElement) {\r\n return Array.from(target.parentNode!.children).indexOf(target);\r\n }\r\n\r\n isTheOnlyBlock() {\r\n return this.api.getBlocksCount() === 1;\r\n }\r\n\r\n\r\n moveBlocks() {\r\n if (!this.isTheOnlyBlock()) {\r\n this.api.move(this.endBlock, this.startBlock);\r\n }\r\n }\r\n}\r\n","export const IconH1: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19 17V10.2135C19 10.1287 18.9011 10.0824 18.836 10.1367L16 12.5\"/></svg>';\r\nexport const IconH2: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 11C16 10 19 9.5 19 12C19 13.9771 16.0684 13.9997 16.0012 16.8981C15.9999 16.9533 16.0448 17 16.1 17L19.3 17\"/></svg>';\r\nexport const IconH3: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 11C16 10.5 16.8323 10 17.6 10C18.3677 10 19.5 10.311 19.5 11.5C19.5 12.5315 18.7474 12.9022 18.548 12.9823C18.5378 12.9864 18.5395 13.0047 18.5503 13.0063C18.8115 13.0456 20 13.3065 20 14.8C20 16 19.5 17 17.8 17C17.8 17 16 17 16 16.3\"/></svg>';\r\nexport const IconH4: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 10L15.2834 14.8511C15.246 14.9178 15.294 15 15.3704 15C16.8489 15 18.7561 15 20.2 15M19 17C19 15.7187 19 14.8813 19 13.6\"/></svg>';\r\nexport const IconH5: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 15.9C16 15.9 16.3768 17 17.8 17C19.5 17 20 15.6199 20 14.7C20 12.7323 17.6745 12.0486 16.1635 12.9894C16.094 13.0327 16 12.9846 16 12.9027V10.1C16 10.0448 16.0448 10 16.1 10H19.8\"/></svg>';\r\nexport const IconH6: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19.5 10C16.5 10.5 16 13.3285 16 15M16 15V15C16 16.1046 16.8954 17 18 17H18.3246C19.3251 17 20.3191 16.3492 20.2522 15.3509C20.0612 12.4958 16 12.6611 16 15Z\"/></svg>';\r\nexport const IconAddBackground: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11 19V19C9.13623 19 8.20435 19 7.46927 18.6955C6.48915 18.2895 5.71046 17.5108 5.30448 16.5307C5 15.7956 5 14.8638 5 13V12C5 9.19108 5 7.78661 5.67412 6.77772C5.96596 6.34096 6.34096 5.96596 6.77772 5.67412C7.78661 5 9.19108 5 12 5H13.5C14.8956 5 15.5933 5 16.1611 5.17224C17.4395 5.56004 18.44 6.56046 18.8278 7.83886C19 8.40666 19 9.10444 19 10.5V10.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 13V16M16 19V16M19 16H16M16 16H13\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6.5 17.5L17.5 6.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18.9919 10.5H19.0015\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10.9919 19H11.0015\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13L13 5\"/></svg>';\r\nexport const IconAddBorder: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18.9919 9.5H19.0015\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.5 5H14.5096\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M14.625 5H15C17.2091 5 19 6.79086 19 9V9.375\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M9.375 5L9 5C6.79086 5 5 6.79086 5 9V9.375\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.3725 5H9.38207\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 9.5H5.00957\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M9.375 19H9C6.79086 19 5 17.2091 5 15V14.625\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.3725 19H9.38207\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 14.55H5.00957\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 13V16M16 19V16M19 16H16M16 16H13\"/></svg>';\r\nexport const IconAlignCenter: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 7L6 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 17H6\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 12L8 12\"/></svg>';\r\nexport const IconAlignJustify: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 7L6 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 17H6\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 12L6 12\"/></svg>';\r\nexport const IconAlignLeft: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M17 7L5 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M17 17H5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M13 12L5 12\"/></svg>';\r\nexport const IconAlignRight: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19 7L7 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19 17H7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19 12L11 12\"/></svg>';\r\nexport const IconBold: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M9 12L9 7.1C9 7.04477 9.04477 7 9.1 7H10.4C11.5 7 14 7.1 14 9.5C14 9.5 14 12 11 12M9 12V16.8C9 16.9105 9.08954 17 9.2 17H12.5C14 17 15 16 15 14.5C15 11.7046 11 12 11 12M9 12H11\"/></svg>';\r\nexport const IconBracketsVertical: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" fill=\"none\" viewBox=\"0 0 20 20\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.6\" d=\"M13.3333 7.5L10 4.16667L6.66668 7.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.6\" d=\"M13.3333 12.5L10 15.8333L6.66668 12.5\"/></svg>';\r\nexport const IconBrackets: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 8L5 12L9 16\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 8L19 12L15 16\"/></svg>';\r\nexport const IconCheck: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7 12L10.4884 15.8372C10.5677 15.9245 10.705 15.9245 10.7844 15.8372L17 9\"/></svg>';\r\nexport const IconChecklist: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M9.2 12L11.0586 13.8586C11.1367 13.9367 11.2633 13.9367 11.3414 13.8586L14.7 10.5\"/><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/></svg>';\r\nexport const IconChevronDown: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7 10L11.8586 14.8586C11.9367 14.9367 12.0633 14.9367 12.1414 14.8586L17 10\"/></svg>';\r\nexport const IconChevronLeft: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M14.5 17.5L9.64142 12.6414C9.56331 12.5633 9.56331 12.4367 9.64142 12.3586L14.5 7.5\"/></svg>';\r\nexport const IconChevronRight: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M9.58284 17.5L14.4414 12.6414C14.5195 12.5633 14.5195 12.4367 14.4414 12.3586L9.58284 7.5\"/></svg>';\r\nexport const IconChevronUp: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7 15L11.8586 10.1414C11.9367 10.0633 12.0633 10.0633 12.1414 10.1414L17 15\"/></svg>';\r\nexport const IconClipboard: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.42857 7H7.71429C7.25963 7 6.82359 7.15804 6.5021 7.43934C6.18061 7.72064 6 8.10218 6 8.5V17.5C6 17.8978 6.18061 18.2794 6.5021 18.5607C6.82359 18.842 7.25963 19 7.71429 19H16.2857C16.7404 19 17.1764 18.842 17.4979 18.5607C17.8194 18.2794 18 17.8978 18 17.5V8.5C18 8.10218 17.8194 7.72064 17.4979 7.43934C17.1764 7.15804 16.7404 7 16.2857 7H14.5714\"/><rect width=\"5.15789\" height=\"3.36842\" x=\"9.42105\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"1.5\"/></svg>';\r\nexport const IconCollapse: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 9L10 12M10 12L7 15M10 12H4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M17 9L14 12M14 12L17 15M14 12H20\"/></svg>';\r\nexport const IconColor: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5.24296 11.4075C5.23167 10.6253 5.52446 9.8395 6.12132 9.24264L9.65686 5.70711C10.0474 5.31658 10.6809 5.31693 11.0714 5.70745L16.0205 10.6565C16.2268 10.8629 16.3243 11.1371 16.3126 11.4075M5.24296 11.4075C5.25382 12.1607 5.54661 12.9106 6.12132 13.4853L8 15.364M5.24296 11.4075H11.9565M16.3126 11.4075C16.3022 11.6487 16.205 11.8869 16.0208 12.0711L12.4853 15.6066C11.3137 16.7782 9.41421 16.7782 8.24264 15.6066L8 15.364M16.3126 11.4075H11.9565M8 15.364L11.9565 11.4075\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M20 17.4615C20 18.3112 19.3284 19 18.5 19C17.6716 19 17 18.3112 17 17.4615C17 16.6119 17.9 15.6154 18.5 15C19.1 15.6154 20 16.6119 20 17.4615Z\"/></svg>';\r\nexport const IconCopy: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M17.25 8.5H10.25C9.2835 8.5 8.5 9.2835 8.5 10.25V17.25C8.5 18.2165 9.2835 19 10.25 19H17.25C18.2165 19 19 18.2165 19 17.25V10.25C19 9.2835 18.2165 8.5 17.25 8.5Z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15.5 8.5V6.75C15.5 6.28587 15.3156 5.84075 14.9874 5.51256C14.6592 5.18437 14.2141 5 13.75 5H6.75C6.28587 5 5.84075 5.18437 5.51256 5.51256C5.18437 5.84075 5 6.28587 5 6.75V13.75C5 14.2141 5.18437 14.6592 5.51256 14.9874C5.84075 15.3156 6.28587 15.5 6.75 15.5H8.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 12L15.5 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 15.5L15.5 15.5\"/></svg>';\r\nexport const IconCross: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M8 8L12 12M12 12L16 16M12 12L16 8M12 12L8 16\"/></svg>';\r\nexport const IconCurlyBrackets: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 17C7 17 7 15.2536 7 13.5L5.5 12L7 10.5C7 8.74644 7 7 9 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 17C17 17 17 15.2536 17 13.5L18.5 12L17 10.5C17 8.74644 17 7 15 7\"/></svg>';\r\nexport const IconDelimiter: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><line x1=\"6\" x2=\"10\" y1=\"12\" y2=\"12\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><line x1=\"14\" x2=\"18\" y1=\"12\" y2=\"12\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/></svg>';\r\nexport const IconDirectionDownRight: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.8833 9.16666L18.2167 12.5M18.2167 12.5L14.8833 15.8333M18.2167 12.5H10.05C9.16594 12.5 8.31809 12.1488 7.69297 11.5237C7.06785 10.8986 6.71666 10.0507 6.71666 9.16666\"/></svg>';\r\nexport const IconDirectionLeftDown: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.9167 14.9167L11.5833 18.25M11.5833 18.25L8.25 14.9167M11.5833 18.25L11.5833 10.0833C11.5833 9.19928 11.9345 8.35143 12.5596 7.72631C13.1848 7.10119 14.0326 6.75 14.9167 6.75\"/></svg>';\r\nexport const IconDirectionRightDown: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.13333 14.9167L12.4667 18.25M12.4667 18.25L15.8 14.9167M12.4667 18.25L12.4667 10.0833C12.4667 9.19928 12.1155 8.35143 11.4904 7.72631C10.8652 7.10119 10.0174 6.75 9.13333 6.75\"/></svg>';\r\nexport const IconDirectionUpRight: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.8833 15.8333L18.2167 12.5M18.2167 12.5L14.8833 9.16667M18.2167 12.5L10.05 12.5C9.16595 12.5 8.31811 12.8512 7.69299 13.4763C7.06787 14.1014 6.71667 14.9493 6.71667 15.8333\"/></svg>';\r\nexport const IconDotCircle: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"4\" stroke=\"currentColor\" stroke-width=\"2\"/></svg>';\r\nexport const IconEtcHorisontal: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M7.30499 11.995L7.30499 12.005M12.005 11.995V12.005M16.705 11.995L16.705 12.005\"/></svg>';\r\nexport const IconEtcVertical: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M12.01 7.29999H12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M12.01 12H12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M12.01 16.7H12\"/></svg>';\r\nexport const IconFile: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13.3236 8.43554L9.49533 12.1908C9.13119 12.5505 8.93118 13.043 8.9393 13.5598C8.94741 14.0767 9.163 14.5757 9.53862 14.947C9.91424 15.3182 10.4191 15.5314 10.9422 15.5397C11.4653 15.5479 11.9637 15.3504 12.3279 14.9908L16.1562 11.2355C16.8845 10.5161 17.2845 9.53123 17.2682 8.4975C17.252 7.46376 16.8208 6.46583 16.0696 5.72324C15.3184 4.98066 14.3086 4.55425 13.2624 4.53782C12.2162 4.52138 11.2193 4.91627 10.4911 5.63562L6.66277 9.39093C5.57035 10.4699 4.97032 11.9473 4.99467 13.4979C5.01903 15.0485 5.66578 16.5454 6.79264 17.6592C7.9195 18.7731 9.43417 19.4127 11.0034 19.4374C12.5727 19.462 14.068 18.8697 15.1604 17.7907L18.9887 14.0354\"/></svg>';\r\nexport const IconGift: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"12\" height=\"6\" x=\"6\" y=\"13\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"2\"/><line x1=\"12\" x2=\"12\" y1=\"9\" y2=\"19\" stroke=\"currentColor\" stroke-width=\"2\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5 11C5 9.89543 5.89543 9 7 9H17C18.1046 9 19 9.89543 19 11V11C19 12.1046 18.1046 13 17 13H7C5.89543 13 5 12.1046 5 11V11Z\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M16 9C16 7.89543 16 6 14 6C12 6 12 7.89543 12 9C12 7.89543 12 6 10 6C8 6 8 7.89543 8 9\"/></svg>';\r\nexport const IconGlobe: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M18 12C18 15.3137 15.3137 18 12 18C8.68629 18 6 15.3137 6 12M18 12C18 8.68629 15.3137 6 12 6C8.68629 6 6 8.68629 6 12M18 12H6M11.7 6C11.7 6 9.7 7.63811 9.7 12C9.7 16.9 11.7 18 11.7 18M12.3 6C12.3 6 14.3 7.63811 14.3 12C14.3 16.9 12.3 18 12.3 18\"/></svg>';\r\nexport const IconHeading: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M9 7L9 12M9 17V12M9 12L15 12M15 7V12M15 17L15 12\"/></svg>';\r\nexport const IconHeart: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M6.6 7.50001C5.27451 8.82549 5.19999 10.6 6.59999 12.3C8 14 12.2 17.9 12.2 17.9C12.2 17.9 16.5 14 17.8 12.3C19.1 10.6 19.1255 8.82549 17.8 7.5C16.4745 6.17452 14.3255 6.17452 13 7.5L12.2 8.30001L11.4 7.50001C10.0745 6.17453 7.92548 6.17453 6.6 7.50001Z\"/></svg>';\r\nexport const IconHidden: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6.77778 6L18.5 17.7222\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10.687 10C10.2473 10.4392 10.0002 11.035 10 11.6564C9.99978 12.2777 10.2465 12.8737 10.6858 13.3132C11.1251 13.7527 11.7211 13.9998 12.3427 14C12.9642 14.0002 13.5604 13.7536 14 13.3144\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 7C17 11.1666 20 11.17 20 11.67C20 12.17 19 13.17 19 13.17M8.2424 8.80936C7.59317 9.22876 6.97961 9.76732 6.4017 10.4251C5.70398 11.2193 5.35512 11.6164 5.35513 12.3702C5.35514 13.124 5.70406 13.5211 6.40191 14.3154C7.99587 16.1297 9.8618 17.0367 12 17.0367C13.1102 17.0367 14.1466 16.7917 15.1111 16.3024\"/></svg>';\r\nexport const IconHtml: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16.6954 5C17.912 5 18.8468 6.07716 18.6755 7.28165L17.426 16.0659C17.3183 16.8229 16.7885 17.4522 16.061 17.6873L12.6151 18.8012C12.2152 18.9304 11.7848 18.9304 11.3849 18.8012L7.93898 17.6873C7.21148 17.4522 6.6817 16.8229 6.57403 16.0659L5.32454 7.28165C5.15322 6.07716 6.088 5 7.30461 5H16.6954Z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 8.4H9L9.42857 11.7939H14.5714L14.3571 13.2788L14.1429 14.7636L12 15.4L9.85714 14.7636L9.77143 14.3394\"/></svg>';\r\nexport const IconInstagram: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M15.9 8.1V8.11\"/><circle cx=\"12\" cy=\"12\" r=\"3\" stroke=\"currentColor\" stroke-width=\"2\"/></svg>';\r\nexport const IconItalic: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M13.34 10C12.4223 12.7337 11 17 11 17\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M14.21 7H14.2\"/></svg>';\r\nexport const IconLink: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7.69998 12.6L7.67896 12.62C6.53993 13.7048 6.52012 15.5155 7.63516 16.625V16.625C8.72293 17.7073 10.4799 17.7102 11.5712 16.6314L13.0263 15.193C14.0703 14.1609 14.2141 12.525 13.3662 11.3266L13.22 11.12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16.22 11.12L16.3564 10.9805C17.2895 10.0265 17.3478 8.5207 16.4914 7.49733V7.49733C15.5691 6.39509 13.9269 6.25143 12.8271 7.17675L11.3901 8.38588C10.0935 9.47674 9.95706 11.4241 11.0888 12.6852L11.12 12.72\"/></svg>';\r\nexport const IconLinkedin: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/><line x1=\"9\" x2=\"9\" y1=\"11.4\" y2=\"15.4\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M9 8.7V8.71\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12 11.4V12M12 15.4V12M12 12C14 11.5 15 11.3611 15 12.5C15 13.5 15 15.4 15 15.4\"/></svg>';\r\nexport const IconListBulleted: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><line x1=\"9\" x2=\"19\" y1=\"7\" y2=\"7\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><line x1=\"9\" x2=\"19\" y1=\"12\" y2=\"12\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><line x1=\"9\" x2=\"19\" y1=\"17\" y2=\"17\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M5.00001 17H4.99002\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M5.00001 12H4.99002\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M5.00001 7H4.99002\"/></svg>';\r\nexport const IconListNumbered: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><line x1=\"12\" x2=\"19\" y1=\"7\" y2=\"7\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><line x1=\"12\" x2=\"19\" y1=\"12\" y2=\"12\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><line x1=\"12\" x2=\"19\" y1=\"17\" y2=\"17\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7.79999 14L7.79999 7.2135C7.79999 7.12872 7.7011 7.0824 7.63597 7.13668L4.79999 9.5\"/></svg>';\r\nexport const IconLoader: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12 6.99998C9.1747 6.99987 6.99997 9.24998 7 12C7.00003 14.55 9.02119 17 12 17C14.7712 17 17 14.75 17 12\"><animateTransform attributeName=\"transform\" attributeType=\"XML\" dur=\"560ms\" from=\"0,12,12\" repeatCount=\"indefinite\" to=\"360,12,12\" type=\"rotate\"/></path></svg>';\r\nexport const IconMarker: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M11.3535 9.31802L12.7678 7.90381C13.5488 7.12276 14.8151 7.12276 15.5962 7.90381C16.3772 8.68486 16.3772 9.95119 15.5962 10.7322L14.182 12.1464M11.3535 9.31802L7.96729 12.7043C7.40889 13.2627 7.02826 13.9739 6.87339 14.7482L6.69798 15.6253C6.55803 16.325 7.17495 16.942 7.87467 16.802L8.75175 16.6266C9.52612 16.4717 10.2373 16.0911 10.7957 15.5327L14.182 12.1464M11.3535 9.31802L14.182 12.1464\"/><line x1=\"15\" x2=\"19\" y1=\"17\" y2=\"17\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/></svg>';\r\nexport const IconMenuSmall: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M9.41 9.66H9.4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M14.6 9.66H14.59\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M9.31 14.36H9.3\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M14.6 14.36H14.59\"/></svg>';\r\nexport const IconMenu: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M9.40999 7.29999H9.4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M14.6 7.29999H14.59\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M9.30999 12H9.3\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M14.6 12H14.59\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M9.40999 16.7H9.4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M14.6 16.7H14.59\"/></svg>';\r\nexport const IconPicture: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5.13968 15.32L8.69058 11.5661C9.02934 11.2036 9.48873 11 9.96774 11C10.4467 11 10.9061 11.2036 11.2449 11.5661L15.3871 16M13.5806 14.0664L15.0132 12.533C15.3519 12.1705 15.8113 11.9668 16.2903 11.9668C16.7693 11.9668 17.2287 12.1705 17.5675 12.533L18.841 13.9634\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13.7778 9.33331H13.7867\"/></svg>';\r\nexport const IconPlay: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M10 10.5606V13.4394C10 14.4777 11.1572 15.0971 12.0211 14.5211L14.1803 13.0817C14.9536 12.5661 14.9503 11.4317 14.18 10.9181L12.0214 9.47907C11.1591 8.9042 10 9.5203 10 10.5606Z\"/><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/></svg>';\r\nexport const IconPlus: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12 7V12M12 17V12M17 12H12M12 12H7\"/></svg>';\r\nexport const IconQuestion: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12 15.52V15.51\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M10.0024 9.97655C10.1567 9.01858 11 8.5 12 8.5C13 8.5 13.6857 9.17188 13.8693 9.70703C14.0529 10.2422 14.0135 11.0514 13.5067 11.5159C13 11.9805 12.7344 11.832 12.2784 12.3168C12.1134 12.4923 12 12.7476 12 12.7476\"/></svg>';\r\nexport const IconQuote: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 10.8182L9 10.8182C8.80222 10.8182 8.60888 10.7649 8.44443 10.665C8.27998 10.5651 8.15181 10.4231 8.07612 10.257C8.00043 10.0909 7.98063 9.90808 8.01922 9.73174C8.0578 9.55539 8.15304 9.39341 8.29289 9.26627C8.43275 9.13913 8.61093 9.05255 8.80491 9.01747C8.99889 8.98239 9.19996 9.00039 9.38268 9.0692C9.56541 9.13801 9.72159 9.25453 9.83147 9.40403C9.94135 9.55353 10 9.72929 10 9.90909L10 12.1818C10 12.664 9.78929 13.1265 9.41421 13.4675C9.03914 13.8084 8.53043 14 8 14\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16 10.8182L15 10.8182C14.8022 10.8182 14.6089 10.7649 14.4444 10.665C14.28 10.5651 14.1518 10.4231 14.0761 10.257C14.0004 10.0909 13.9806 9.90808 14.0192 9.73174C14.0578 9.55539 14.153 9.39341 14.2929 9.26627C14.4327 9.13913 14.6109 9.05255 14.8049 9.01747C14.9989 8.98239 15.2 9.00039 15.3827 9.0692C15.5654 9.13801 15.7216 9.25453 15.8315 9.40403C15.9414 9.55353 16 9.72929 16 9.90909L16 12.1818C16 12.664 15.7893 13.1265 15.4142 13.4675C15.0391 13.8084 14.5304 14 14 14\"/></svg>';\r\nexport const IconRedo: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.6667 13.6667L18 10.3333L14.6667 7M18 10.3333H8.83333C7.94928 10.3333 7.10143 10.6845 6.47631 11.3096C5.85119 11.9348 5.5 12.7826 5.5 13.6667C5.5 14.5507 5.85119 15.3986 6.47631 16.0237C7.10143 16.6488 7.94928 17 8.83333 17H9.66667\"/></svg>';\r\nexport const IconRemoveBackground: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11 19V19C9.13623 19 8.20435 19 7.46927 18.6955C6.48915 18.2895 5.71046 17.5108 5.30448 16.5307C5 15.7956 5 14.8638 5 13V12C5 9.19108 5 7.78661 5.67412 6.77772C5.96596 6.34096 6.34096 5.96596 6.77772 5.67412C7.78661 5 9.19108 5 12 5H13.5C14.8956 5 15.5933 5 16.1611 5.17224C17.4395 5.56004 18.44 6.56046 18.8278 7.83886C19 8.40666 19 9.10444 19 10.5V10.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19.1187 14.8787L16.9974 17M14.876 19.1213L16.9974 17M19.1187 19.1213L16.9974 17M16.9974 17L14.876 14.8787\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6.5 17.5L17.5 6.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18.9919 10.5H19.0015\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10.9919 19H11.0015\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13L13 5\"/></svg>';\r\nexport const IconReplace: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M11.5 17.5L5 11M5 11V15.5M5 11H9.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12.5 6.5L19 13M19 13V8.5M19 13H14.5\"/></svg>';\r\nexport const IconSave: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M15.078 5.62637L15.6153 4.78296L15.078 5.62637C15.4261 5.84808 15.7393 6.15354 16.5711 6.98528L17.2782 6.27817L16.5711 6.98528L17.5251 7.93934C17.8347 8.2489 17.9496 8.36494 18.0489 8.48177C18.5907 9.11982 18.9188 9.91178 18.9868 10.7461C18.9992 10.8989 19 11.0622 19 11.5V12C19 13.4166 18.9992 14.419 18.9352 15.2026C18.8721 15.9745 18.7527 16.4457 18.564 16.816C18.1805 17.5686 17.5686 18.1805 16.816 18.564C16.4457 18.7527 15.9745 18.8721 15.2026 18.9352C14.419 18.9992 13.4166 19 12 19C10.5834 19 9.58104 18.9992 8.79744 18.9352C8.02552 18.8721 7.55435 18.7527 7.18404 18.564C6.43139 18.1805 5.81947 17.5686 5.43597 16.816C5.24729 16.4457 5.12787 15.9745 5.0648 15.2026C5.00078 14.419 5 13.4166 5 12V11.7782C5 10.4673 5.00067 9.53987 5.05572 8.81299C5.10998 8.09655 5.21284 7.65673 5.37487 7.3093C5.77229 6.45718 6.45718 5.77229 7.3093 5.37487C7.65673 5.21284 8.09655 5.10998 8.81299 5.05572C9.53986 5.00067 10.4673 5 11.7782 5C12.9544 5 13.3919 5.00552 13.7948 5.09484C14.2503 5.19583 14.6846 5.37572 15.078 5.62637Z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 15C13.1046 15 14 14.1046 14 13C14 11.8954 13.1046 11 12 11C10.8954 11 10 11.8954 10 13C10 14.1046 10.8954 15 12 15Z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14 5.5V7C14 7.55228 13.5523 8 13 8H11C10.4477 8 10 7.55228 10 7V5.2\"/></svg>';\r\nexport const IconSearch: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><circle cx=\"10.5\" cy=\"10.5\" r=\"5.5\" stroke=\"currentColor\" stroke-width=\"2\"/><line x1=\"15.4142\" x2=\"19\" y1=\"15\" y2=\"18.5858\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/></svg>';\r\nexport const IconStar: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M11.8197 6.04369C11.8924 5.8925 12.1076 5.8925 12.1803 6.04369L13.9776 9.78496C14.0068 9.84564 14.0645 9.88759 14.1312 9.89657L18.2448 10.4498C18.411 10.4722 18.4776 10.6769 18.3562 10.7927L15.3535 13.6582C15.3048 13.7047 15.2827 13.7726 15.2948 13.8388L16.0398 17.922C16.0699 18.087 15.8957 18.2136 15.7481 18.1339L12 16.1124L8.25192 18.1339C8.10429 18.2136 7.93012 18.087 7.96022 17.922L8.7052 13.8388C8.71728 13.7726 8.69523 13.7047 8.64652 13.6582L5.64378 10.7927C5.52244 10.6769 5.58896 10.4722 5.7552 10.4498L9.86876 9.89657C9.93549 9.88759 9.99322 9.84564 10.0224 9.78496L11.8197 6.04369Z\"/></svg>';\r\nexport const IconStretch: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M17 9L20 12L17 15\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14 12H20\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 9L4 12L7 15\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 12H10\"/></svg>';\r\nexport const IconStrikethrough: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.5 8.50001C13.5 7 10.935 6.66476 9.75315 7.79706C9.27092 8.25909 9 8.88574 9 9.53915C9 10.1926 9.27092 10.8192 9.75315 11.2812C10.9835 12.46 13.0165 11.5457 14.2468 12.7244C14.7291 13.1865 15 13.8131 15 14.4665C15 15.1199 14.7291 15.7466 14.2468 16.2086C12.8659 17.5317 10 17.5 9 16\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 12H18\"/></svg>';\r\nexport const IconTableWithHeadings: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5 10H19\"/><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/></svg>';\r\nexport const IconTableWithoutHeadings: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M10 5V18.5\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M14 5V18.5\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5 10H19\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5 14H19\"/><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/></svg>';\r\nexport const IconTable: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M10 5V18.5\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5 10H19\"/><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/></svg>';\r\nexport const IconText: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M8 9V7.2C8 7.08954 8.08954 7 8.2 7L12 7M16 9V7.2C16 7.08954 15.9105 7 15.8 7L12 7M12 7L12 17M12 17H10M12 17H14\"/></svg>';\r\nexport const IconTranslate: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7 17C8 14.5 12 12 13 9\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M8.5 11C8.5 11 10 14 12.5 15\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7.7H16M11 7.7V5.7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M14.5 18L15.2143 16M15.2143 16L16.9159 11.2354C16.9663 11.0942 17.1001 11 17.25 11C17.3999 11 17.5337 11.0942 17.5841 11.2354L19.2857 16M15.2143 16H19.2857M20 18L19.2857 16\"/></svg>';\r\nexport const IconTrash: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18.1328 7.7234C18.423 7.7634 18.7115 7.80571 19 7.85109M18.1328 7.7234L17.2267 17.4023C17.1897 17.8371 16.973 18.2432 16.62 18.5394C16.267 18.8356 15.8037 19.0001 15.3227 19H8.67733C8.19632 19.0001 7.73299 18.8356 7.37998 18.5394C7.02698 18.2432 6.81032 17.8371 6.77333 17.4023L5.86715 7.7234M18.1328 7.7234C17.1536 7.58919 16.1693 7.48733 15.1818 7.41803M5.86715 7.7234C5.57697 7.76263 5.28848 7.80494 5 7.85032M5.86715 7.7234C6.84642 7.58919 7.83074 7.48733 8.81818 7.41803M15.1818 7.41803C13.0638 7.26963 10.9362 7.26963 8.81818 7.41803M15.1818 7.41803C15.1818 5.30368 13.7266 4.34834 12 4.34834C10.2734 4.34834 8.81818 5.43945 8.81818 7.41803\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10.5 15.5L10 11\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14 11L13.5 15.5\"/></svg>';\r\nexport const IconTwitter: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16.7893 7.87697C17.5 8 18.5 8 18.5 8C18.5 8 17.5 9.5 17.5 10C18.5 18.5 11.5 20.5 5.5 16.5C6.99996 16.6712 8.04617 16.5163 9.25234 15.6024C7.99546 15.58 5.36548 13.6033 5 12.5C6.5 13 8 12 8 12C6.52134 11.0446 4.93005 9.24114 5.97461 7.50832C7.39125 9.18838 9.50766 10.2939 11.8948 10.4097C11.2198 7.60755 14.9218 5.95341 16.7893 7.87697Z\"/></svg>';\r\nexport const IconUnderline: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 7.5V11.5C9 12.2956 9.31607 13.0587 9.87868 13.6213C10.4413 14.1839 11.2044 14.5 12 14.5C12.7956 14.5 13.5587 14.1839 14.1213 13.6213C14.6839 13.0587 15 12.2956 15 11.5V7.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7.71429 18H16.2857\"/></svg>';\r\nexport const IconUndo: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.33333 13.6667L6 10.3333L9.33333 7M6 10.3333H15.1667C16.0507 10.3333 16.8986 10.6845 17.5237 11.3096C18.1488 11.9348 18.5 12.7826 18.5 13.6667C18.5 14.5507 18.1488 15.3986 17.5237 16.0237C16.8986 16.6488 16.0507 17 15.1667 17H14.3333\"/></svg>';\r\nexport const IconUnlink: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M15.7795 11.5C15.7795 11.5 16.053 11.1962 16.5497 10.6722C17.4442 9.72856 17.4701 8.2475 16.5781 7.30145V7.30145C15.6482 6.31522 14.0873 6.29227 13.1288 7.25073L11.8796 8.49999\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M8.24517 12.3883C8.24517 12.3883 7.97171 12.6922 7.47504 13.2161C6.58051 14.1598 6.55467 15.6408 7.44666 16.5869V16.5869C8.37653 17.5731 9.93744 17.5961 10.8959 16.6376L12.1452 15.3883\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M17.7802 15.1032L16.597 14.9422C16.0109 14.8624 15.4841 15.3059 15.4627 15.8969L15.4199 17.0818\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6.39064 9.03238L7.58432 9.06668C8.17551 9.08366 8.6522 8.58665 8.61056 7.99669L8.5271 6.81397\"/><line x1=\"12.1142\" x2=\"11.7\" y1=\"12.2\" y2=\"11.7858\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/></svg>';\r\nexport const IconUser: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M12 10C12.7145 10 13.239 9.56559 13.5392 9.11536C13.844 8.65814 14 8.0841 14 7.5C14 6.9159 13.844 6.34186 13.5392 5.88464C13.239 5.43441 12.7145 5 12 5C11.2855 5 10.761 5.43441 10.4608 5.88464C10.156 6.34186 10 6.9159 10 7.5C10 8.0841 10.156 8.65814 10.4608 9.11536C10.761 9.56559 11.2855 10 12 10Z\"/><ellipse cx=\"12\" cy=\"16\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"3\" ry=\"5\" transform=\"rotate(-90 12 16)\"/></svg>';\r\nexport const IconUsersGroup: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M10 10C10.7145 10 11.239 9.56559 11.5392 9.11536C11.844 8.65814 12 8.0841 12 7.5C12 6.9159 11.844 6.34186 11.5392 5.88464C11.239 5.43441 10.7145 5 10 5C9.28547 5 8.761 5.43441 8.46084 5.88464C8.15603 6.34186 8 6.9159 8 7.5C8 8.0841 8.15603 8.65814 8.46084 9.11536C8.761 9.56559 9.28547 10 10 10Z\"/><ellipse cx=\"10\" cy=\"16\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"3\" ry=\"5\" transform=\"rotate(-90 10 16)\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M15.5555 10.2222C16.5374 10.2222 17.3333 9.42629 17.3333 8.44445C17.3333 7.46261 16.5374 6.66667 15.5555 6.66667\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M17.5 13C21 14.5 20.5 18 18 18.5\"/></svg>';\r\nexport const IconWarning: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/><line x1=\"12\" x2=\"12\" y1=\"9\" y2=\"12\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12 15.02V15.01\"/></svg>';\r\n\r\nexport const IconToolboxAlert: string = '<?xml version=\"1.0\" standalone=\"no\"?><!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"><svg t=\"1763693072662\" class=\"icon\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"2633\" id=\"mx_n_1763693072663\" width=\"24\" height=\"24\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><path d=\"M83.2 147.2V448c0 25.6 19.2 44.8 44.8 44.8h768c25.6 0 44.8-19.2 44.8-44.8V147.2c0-25.6-19.2-44.8-44.8-44.8H128c-25.6 6.4-44.8 25.6-44.8 44.8z m89.6 256V192h684.8v211.2H172.8zM810.24 642.56c0-25.6-19.2-44.8-44.8-44.8h-640c-25.6 0-44.8 19.2-44.8 44.8 0 25.6 19.2 44.8 44.8 44.8h640c25.6 6.4 44.8-12.8 44.8-44.8zM554.56 866.24c0-25.6-19.2-44.8-44.8-44.8h-384c-25.6 0-44.8 19.2-44.8 44.8 0 25.6 19.2 44.8 44.8 44.8h384c25.6 6.4 44.8-12.8 44.8-44.8z\" fill=\"#262626\" p-id=\"2634\"></path></svg>';\r\n\r\nexport const IconCode: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 17C7 17 7 15.2536 7 13.5L5.5 12L7 10.5C7 8.74644 7 7 9 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 17C17 17 17 15.2536 17 13.5L18.5 12L17 10.5C17 8.74644 17 7 15 7\"/></svg>';\r\n\r\nexport const IconIndentLeft: string = '<svg t=\"1763708081701\" class=\"icon\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"2604\" width=\"24\" height=\"24\"><path d=\"M469.3330000000001 725.333H896V640H469.3330000000001v85.333zM128 512l170.667 170.667V341.3330000000001L128 512z m0 384h768v-85.333H128V896z m0-768v85.333h768V128H128z m341.333 256H896v-85.333H469.3330000000001V384z m0 170.667H896v-85.334H469.3330000000001v85.334z\" p-id=\"2605\" fill=\"#000000\"></path></svg>';\r\nexport const IconIndentRight: string = '<svg t=\"1763708124227\" class=\"icon\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"2788\" width=\"24\" height=\"24\"><path d=\"M128 896h768v-85.333H128V896z m0-554.667v341.334L298.667 512 128 341.333z m341.333 384H896V640H469.333v85.333zM128 128v85.333h768V128H128z m341.333 256H896v-85.333H469.333V384z m0 170.667H896v-85.334H469.333v85.334z\" p-id=\"2789\" fill=\"#000000\"></path></svg>';\r\n\r\n\r\nexport const IconNumber = '<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 14.2L10 7.4135C10 7.32872 9.90111 7.28241 9.83598 7.33668L7 9.7\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M13.2087 14.2H13.2\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/></svg>';\r\nexport const IconLowerRoman = '<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13.2087 14.2H13.2\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M10 14.2L10 9.5\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M10 7.01L10 7\" stroke=\"black\" stroke-width=\"1.8\" stroke-linecap=\"round\"/></svg>';\r\nexport const IconUpperRoman = '<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13.2087 14.2H13.2\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M10 14.2L10 7.2\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/></svg>';\r\nexport const IconUpperAlpha = '<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M16.0087 14.2H16\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M7 14.2L7.78865 12M13 14.2L12.1377 12M7.78865 12C7.78865 12 9.68362 7 10 7C10.3065 7 12.1377 12 12.1377 12M7.78865 12L12.1377 12\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/></svg>';\r\nexport const IconLowerAlpha = '<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M14.2087 14.2H14.2\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M11.5 14.5C11.5 14.5 11 13.281 11 12.5M7 9.5C7 9.5 7.5 8.5 9 8.5C10.5 8.5 11 9.5 11 10.5L11 11.5M11 11.5L11 12.5M11 11.5C11 11.5 7 11 7 13C7 15.3031 11 15 11 12.5\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/></svg>';\r\nexport const IconStartWith = '<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8 14.2L8 7.4135C8 7.32872 7.90111 7.28241 7.83598 7.33668L5 9.7\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M14 13L16.4167 10.7778M16.4167 10.7778L14 8.5M16.4167 10.7778H11.6562\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>';\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\n\r\n\r\nimport { API, PasteEvent } from '@ebl-vue/editorjs';\r\nimport type { HeaderData, HeaderConfig, Level } from './types';\r\nimport type { BlockTool,BlockToolConstructorOptions } from '@ebl-vue/editorjs';\r\n\r\nimport { IconH1 } from '../../icons';\r\n\r\n\r\n\r\n/**\r\n * Header block for the Editor.js.\r\n *\r\n * @author CodeX (team@ifmo.su)\r\n * @copyright CodeX 2018\r\n * @license MIT\r\n * @version 2.0.0\r\n */\r\nexport default class H1 implements BlockTool {\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {{data: HeaderData, config: HeaderConfig, api: object}}\r\n * data — previously saved data\r\n * config - user config for Tool\r\n * api - Editor.js API\r\n * readOnly - read only mode flag\r\n */\r\n /**\r\n * Editor.js API\r\n * @private\r\n */\r\n private api: API;\r\n /**\r\n * Read-only mode flag\r\n * @private\r\n */\r\n private readOnly: boolean;\r\n /**\r\n * Tool's settings passed from Editor\r\n * @private\r\n */\r\n private _settings: HeaderConfig;\r\n /**\r\n * Block's data\r\n * @private\r\n */\r\n private _data: HeaderData;\r\n /**\r\n * Main Block wrapper\r\n * @private\r\n */\r\n private _element: HTMLHeadingElement;\r\n\r\n \r\n\r\n constructor({ data, config, api, readOnly }: BlockToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n /**\r\n * Tool's settings passed from Editor\r\n *\r\n * @type {HeaderConfig}\r\n * @private\r\n */\r\n this._settings={placeholder:\"H1\"};\r\n\r\n /**\r\n * Block's data\r\n *\r\n * @type {HeaderData}\r\n * @private\r\n */\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * Main Block wrapper\r\n *\r\n * @type {HTMLElement}\r\n * @private\r\n */\r\n this._element = this.getTag();\r\n\r\n }\r\n /**\r\n * Styles\r\n */\r\n private get _CSS() {\r\n return {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-header',\r\n };\r\n }\r\n\r\n /**\r\n * Check if data is valid\r\n * \r\n * @param {any} data - data to check\r\n * @returns {data is HeaderData}\r\n * @private\r\n */\r\n isHeaderData(data: any): data is HeaderData {\r\n return (data as HeaderData).text !== undefined;\r\n }\r\n\r\n /**\r\n * Normalize input data\r\n *\r\n * @param {HeaderData} data - saved data to process\r\n *\r\n * @returns {HeaderData}\r\n * @private\r\n */\r\n normalizeData(data: HeaderData | {}): HeaderData {\r\n const newData: HeaderData = { text: '', level: this.defaultLevel.number };\r\n\r\n if (this.isHeaderData(data)) {\r\n newData.text = data.text || '';\r\n \r\n if (data.level !== undefined && !isNaN(parseInt(data.level.toString()))) {\r\n newData.level = parseInt(data.level.toString());\r\n }\r\n }\r\n\r\n return newData;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLHeadingElement}\r\n * @public\r\n */\r\n render(): HTMLHeadingElement {\r\n return this._element;\r\n }\r\n\r\n\r\n /**\r\n * Callback for Block's settings buttons\r\n *\r\n * @param {number} level - level to set\r\n */\r\n setLevel(level: number): void {\r\n this.data = {\r\n level: level,\r\n text: this.data.text,\r\n };\r\n }\r\n\r\n /**\r\n * Method that specified how to merge two Text blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * @param {HeaderData} data - saved data to merger with current block\r\n * @public\r\n */\r\n merge(data: HeaderData): void {\r\n this._element.insertAdjacentHTML('beforeend', data.text)\r\n }\r\n\r\n /**\r\n * Validate Text block data:\r\n * - check for emptiness\r\n *\r\n * @param {HeaderData} blockData — data received after saving\r\n * @returns {boolean} false if saved data is not correct, otherwise true\r\n * @public\r\n */\r\n validate(blockData: HeaderData): boolean {\r\n return blockData.text.trim() !== '';\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n *\r\n * @param {HTMLHeadingElement} toolsContent - Text tools rendered view\r\n * @returns {HeaderData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLHeadingElement): HeaderData {\r\n return {\r\n text: toolsContent.innerHTML,\r\n level: this.defaultLevel.number,\r\n };\r\n }\r\n\r\n /**\r\n * Allow Header to be converted to/from other blocks\r\n */\r\n static get conversionConfig() {\r\n return {\r\n export: 'text', // use 'text' property for other blocks\r\n import: 'text', // fill 'text' property from other block's export string\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer Rules\r\n */\r\n static get sanitize() {\r\n return {\r\n level: false,\r\n text: {},\r\n };\r\n }\r\n\r\n /**\r\n * Returns true to notify core that read-only is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get current Tools`s data\r\n *\r\n * @returns {HeaderData} Current data\r\n * @private\r\n */\r\n get data(): HeaderData {\r\n this._data.text = this._element.innerHTML;\r\n this._data.level = this.defaultLevel.number;\r\n \r\n return this._data;\r\n }\r\n\r\n /**\r\n * Store data in plugin:\r\n * - at the this._data property\r\n * - at the HTML\r\n *\r\n * @param {HeaderData} data — data to set\r\n * @private\r\n */\r\n set data(data: HeaderData) {\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * If level is set and block in DOM\r\n * then replace it to a new block\r\n */\r\n if (data.level !== undefined && this._element.parentNode) {\r\n /**\r\n * Create a new tag\r\n *\r\n * @type {HTMLHeadingElement}\r\n */\r\n const newHeader = this.getTag();\r\n\r\n /**\r\n * Save Block's content\r\n */\r\n newHeader.innerHTML = this._element.innerHTML;\r\n\r\n /**\r\n * Replace blocks\r\n */\r\n this._element.parentNode.replaceChild(newHeader, this._element);\r\n\r\n /**\r\n * Save new block to private variable\r\n *\r\n * @type {HTMLHeadingElement}\r\n * @private\r\n */\r\n this._element = newHeader;\r\n }\r\n\r\n /**\r\n * If data.text was passed then update block's content\r\n */\r\n if (data.text !== undefined) {\r\n this._element.innerHTML = this._data.text || '';\r\n }\r\n }\r\n\r\n /**\r\n * Get tag for target level\r\n * By default returns second-leveled header\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n getTag(): HTMLHeadingElement {\r\n const tag = this.createHeadingElement();\r\n this.setElementContent(tag);\r\n this.addStylesToElement(tag);\r\n this.setEditability(tag);\r\n this.addPlaceholder(tag);\r\n return tag;\r\n }\r\n\r\n /**\r\n * 创建标题元素\r\n * @returns {HTMLHeadingElement} 创建的HTML标题元素\r\n * @private\r\n */\r\n private createHeadingElement(): HTMLHeadingElement {\r\n return document.createElement(this.defaultLevel.tag) as HTMLHeadingElement;\r\n }\r\n\r\n /**\r\n * 设置元素内容\r\n * @param {HTMLHeadingElement} element - 要设置内容的HTML标题元素\r\n * @private\r\n */\r\n private setElementContent(element: HTMLHeadingElement): void {\r\n element.innerHTML = this._data.text || '';\r\n }\r\n\r\n /**\r\n * 为元素添加样式类\r\n * @param {HTMLHeadingElement} element - 要添加样式的HTML标题元素\r\n * @private\r\n */\r\n private addStylesToElement(element: HTMLHeadingElement): void {\r\n element.classList.add(this._CSS.wrapper);\r\n }\r\n\r\n /**\r\n * 设置元素可编辑属性\r\n * @param {HTMLHeadingElement} element - 要设置编辑属性的HTML标题元素\r\n * @private\r\n */\r\n private setEditability(element: HTMLHeadingElement): void {\r\n element.contentEditable = this.readOnly ? 'false' : 'true';\r\n }\r\n\r\n /**\r\n * 为元素添加占位符文本\r\n * @param {HTMLHeadingElement} element - 要添加占位符的HTML标题元素\r\n * @private\r\n */\r\n private addPlaceholder(element: HTMLHeadingElement): void {\r\n element.dataset.placeholder = this.api.i18n.t(this._settings.placeholder || '');\r\n }\r\n\r\n\r\n\r\n /**\r\n * Return default level\r\n *\r\n * @returns {level}\r\n */\r\n get defaultLevel(): Level {\r\n return {\r\n number: 1,\r\n tag: 'H1',\r\n svg: IconH1,\r\n };\r\n }\r\n\r\n\r\n\r\n\r\n /**\r\n * Handle H1-H6 tags on paste to substitute it with header Tool\r\n *\r\n * @param {PasteEvent} event - event with pasted content\r\n */\r\n onPaste(event: PasteEvent): void {\r\n const detail = event.detail;\r\n\r\n if ('data' in detail) {\r\n const content = detail.data as HTMLElement;\r\n this.data = {\r\n level: 1,\r\n text: content.innerHTML,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Used by Editor.js paste handling API.\r\n * Provides configuration to handle H1-H6 tags.\r\n *\r\n * @returns {{handler: (function(HTMLElement): {text: string}), tags: string[]}}\r\n */\r\n static get pasteConfig() {\r\n return {\r\n tags: ['H1'],\r\n };\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @returns {{icon: string, title: string}}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: IconH1,\r\n title: 'H1'\r\n };\r\n }\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\n\r\n\r\nimport { API, PasteEvent } from '@ebl-vue/editorjs';\r\nimport type { HeaderData, HeaderConfig, Level } from './types';\r\nimport type { BlockTool, BlockToolConstructorOptions } from '@ebl-vue/editorjs';\r\nimport { IconH2 } from '../../icons';\r\n\r\n\r\n\r\n/**\r\n * Header block for the Editor.js.\r\n *\r\n * @author CodeX (team@ifmo.su)\r\n * @copyright CodeX 2018\r\n * @license MIT\r\n * @version 2.0.0\r\n */\r\nexport default class H2 implements BlockTool {\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {{data: HeaderData, config: HeaderConfig, api: object}}\r\n * data — previously saved data\r\n * config - user config for Tool\r\n * api - Editor.js API\r\n * readOnly - read only mode flag\r\n */\r\n /**\r\n * Editor.js API\r\n * @private\r\n */\r\n private api: API;\r\n /**\r\n * Read-only mode flag\r\n * @private\r\n */\r\n private readOnly: boolean;\r\n /**\r\n * Tool's settings passed from Editor\r\n * @private\r\n */\r\n private _settings: HeaderConfig;\r\n /**\r\n * Block's data\r\n * @private\r\n */\r\n private _data: HeaderData;\r\n /**\r\n * Main Block wrapper\r\n * @private\r\n */\r\n private _element: HTMLHeadingElement;\r\n\r\n \r\n\r\n constructor({ data, config, api, readOnly }: BlockToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n /**\r\n * Tool's settings passed from Editor\r\n *\r\n * @type {HeaderConfig}\r\n * @private\r\n */\r\n this._settings={placeholder:\"H2\"};\r\n\r\n /**\r\n * Block's data\r\n *\r\n * @type {HeaderData}\r\n * @private\r\n */\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * Main Block wrapper\r\n *\r\n * @type {HTMLElement}\r\n * @private\r\n */\r\n this._element = this.getTag();\r\n }\r\n /**\r\n * Styles\r\n */\r\n private get _CSS() {\r\n return {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-header',\r\n };\r\n }\r\n\r\n /**\r\n * Check if data is valid\r\n * \r\n * @param {any} data - data to check\r\n * @returns {data is HeaderData}\r\n * @private\r\n */\r\n isHeaderData(data: any): data is HeaderData {\r\n return (data as HeaderData).text !== undefined;\r\n }\r\n\r\n /**\r\n * Normalize input data\r\n *\r\n * @param {HeaderData} data - saved data to process\r\n *\r\n * @returns {HeaderData}\r\n * @private\r\n */\r\n normalizeData(data: HeaderData | {}): HeaderData {\r\n const newData: HeaderData = { text: '', level: this.defaultLevel.number };\r\n\r\n if (this.isHeaderData(data)) {\r\n newData.text = data.text || '';\r\n \r\n if (data.level !== undefined && !isNaN(parseInt(data.level.toString()))) {\r\n newData.level = parseInt(data.level.toString());\r\n }\r\n }\r\n\r\n return newData;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLHeadingElement}\r\n * @public\r\n */\r\n render(): HTMLHeadingElement {\r\n return this._element;\r\n }\r\n\r\n\r\n /**\r\n * Callback for Block's settings buttons\r\n *\r\n * @param {number} level - level to set\r\n */\r\n setLevel(level: number): void {\r\n this.data = {\r\n level: level,\r\n text: this.data.text,\r\n };\r\n }\r\n\r\n /**\r\n * Method that specified how to merge two Text blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * @param {HeaderData} data - saved data to merger with current block\r\n * @public\r\n */\r\n merge(data: HeaderData): void {\r\n this._element.insertAdjacentHTML('beforeend', data.text)\r\n }\r\n\r\n /**\r\n * Validate Text block data:\r\n * - check for emptiness\r\n *\r\n * @param {HeaderData} blockData — data received after saving\r\n * @returns {boolean} false if saved data is not correct, otherwise true\r\n * @public\r\n */\r\n validate(blockData: HeaderData): boolean {\r\n return blockData.text.trim() !== '';\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n *\r\n * @param {HTMLHeadingElement} toolsContent - Text tools rendered view\r\n * @returns {HeaderData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLHeadingElement): HeaderData {\r\n return {\r\n text: toolsContent.innerHTML,\r\n level: this.defaultLevel.number,\r\n };\r\n }\r\n\r\n /**\r\n * Allow Header to be converted to/from other blocks\r\n */\r\n static get conversionConfig() {\r\n return {\r\n export: 'text', // use 'text' property for other blocks\r\n import: 'text', // fill 'text' property from other block's export string\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer Rules\r\n */\r\n static get sanitize() {\r\n return {\r\n level: false,\r\n text: {},\r\n };\r\n }\r\n\r\n /**\r\n * Returns true to notify core that read-only is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get current Tools`s data\r\n *\r\n * @returns {HeaderData} Current data\r\n * @private\r\n */\r\n get data(): HeaderData {\r\n this._data.text = this._element.innerHTML;\r\n this._data.level = this.defaultLevel.number;\r\n \r\n return this._data;\r\n }\r\n\r\n /**\r\n * Store data in plugin:\r\n * - at the this._data property\r\n * - at the HTML\r\n *\r\n * @param {HeaderData} data — data to set\r\n * @private\r\n */\r\n set data(data: HeaderData) {\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * If level is set and block in DOM\r\n * then replace it to a new block\r\n */\r\n if (data.level !== undefined && this._element.parentNode) {\r\n /**\r\n * Create a new tag\r\n *\r\n * @type {HTMLHeadingElement}\r\n */\r\n const newHeader = this.getTag();\r\n\r\n /**\r\n * Save Block's content\r\n */\r\n newHeader.innerHTML = this._element.innerHTML;\r\n\r\n /**\r\n * Replace blocks\r\n */\r\n this._element.parentNode.replaceChild(newHeader, this._element);\r\n\r\n /**\r\n * Save new block to private variable\r\n *\r\n * @type {HTMLHeadingElement}\r\n * @private\r\n */\r\n this._element = newHeader;\r\n }\r\n\r\n /**\r\n * If data.text was passed then update block's content\r\n */\r\n if (data.text !== undefined) {\r\n this._element.innerHTML = this._data.text || '';\r\n }\r\n }\r\n\r\n /**\r\n * Get tag for target level\r\n * By default returns second-leveled header\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n getTag(): HTMLHeadingElement {\r\n const tag = this.createHeadingElement();\r\n this.setElementContent(tag);\r\n this.addStylesToElement(tag);\r\n this.setEditability(tag);\r\n this.addPlaceholder(tag);\r\n return tag;\r\n }\r\n\r\n /**\r\n * 创建标题元素\r\n * @returns {HTMLHeadingElement} 创建的HTML标题元素\r\n * @private\r\n */\r\n private createHeadingElement(): HTMLHeadingElement {\r\n return document.createElement(this.defaultLevel.tag) as HTMLHeadingElement;\r\n }\r\n\r\n /**\r\n * 设置元素内容\r\n * @param {HTMLHeadingElement} element - 要设置内容的HTML标题元素\r\n * @private\r\n */\r\n private setElementContent(element: HTMLHeadingElement): void {\r\n element.innerHTML = this._data.text || '';\r\n }\r\n\r\n /**\r\n * 为元素添加样式类\r\n * @param {HTMLHeadingElement} element - 要添加样式的HTML标题元素\r\n * @private\r\n */\r\n private addStylesToElement(element: HTMLHeadingElement): void {\r\n element.classList.add(this._CSS.wrapper);\r\n }\r\n\r\n /**\r\n * 设置元素可编辑属性\r\n * @param {HTMLHeadingElement} element - 要设置编辑属性的HTML标题元素\r\n * @private\r\n */\r\n private setEditability(element: HTMLHeadingElement): void {\r\n element.contentEditable = this.readOnly ? 'false' : 'true';\r\n }\r\n\r\n /**\r\n * 为元素添加占位符文本\r\n * @param {HTMLHeadingElement} element - 要添加占位符的HTML标题元素\r\n * @private\r\n */\r\n private addPlaceholder(element: HTMLHeadingElement): void {\r\n element.dataset.placeholder = this.api.i18n.t(this._settings.placeholder || '');\r\n }\r\n\r\n\r\n\r\n /**\r\n * Return default level\r\n *\r\n * @returns {level}\r\n */\r\n get defaultLevel(): Level {\r\n return {\r\n number: 2,\r\n tag: 'H2',\r\n svg: IconH2,\r\n };\r\n }\r\n\r\n\r\n\r\n\r\n /**\r\n * Handle H1-H6 tags on paste to substitute it with header Tool\r\n *\r\n * @param {PasteEvent} event - event with pasted content\r\n */\r\n onPaste(event: PasteEvent): void {\r\n const detail = event.detail;\r\n\r\n if ('data' in detail) {\r\n const content = detail.data as HTMLElement;\r\n this.data = {\r\n level: 2,\r\n text: content.innerHTML,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Used by Editor.js paste handling API.\r\n * Provides configuration to handle H1-H6 tags.\r\n *\r\n * @returns {{handler: (function(HTMLElement): {text: string}), tags: string[]}}\r\n */\r\n static get pasteConfig() {\r\n return {\r\n tags: ['H2'],\r\n };\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @returns {{icon: string, title: string}}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: IconH2,\r\n title: 'H2',\r\n };\r\n }\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\n\r\n\r\nimport { API, PasteEvent } from '@ebl-vue/editorjs';\r\nimport type { HeaderData, HeaderConfig, Level } from './types';\r\nimport type { BlockTool, BlockToolConstructorOptions } from '@ebl-vue/editorjs';\r\n\r\nimport { IconH3 } from '../../icons';\r\n\r\n\r\n\r\n/**\r\n * Header block for the Editor.js.\r\n *\r\n * @author CodeX (team@ifmo.su)\r\n * @copyright CodeX 2018\r\n * @license MIT\r\n * @version 2.0.0\r\n */\r\nexport default class H3 implements BlockTool {\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {{data: HeaderData, config: HeaderConfig, api: object}}\r\n * data — previously saved data\r\n * config - user config for Tool\r\n * api - Editor.js API\r\n * readOnly - read only mode flag\r\n */\r\n /**\r\n * Editor.js API\r\n * @private\r\n */\r\n private api: API;\r\n /**\r\n * Read-only mode flag\r\n * @private\r\n */\r\n private readOnly: boolean;\r\n /**\r\n * Tool's settings passed from Editor\r\n * @private\r\n */\r\n private _settings: HeaderConfig;\r\n /**\r\n * Block's data\r\n * @private\r\n */\r\n private _data: HeaderData;\r\n /**\r\n * Main Block wrapper\r\n * @private\r\n */\r\n private _element: HTMLHeadingElement;\r\n\r\n \r\n\r\n constructor({ data, config, api, readOnly }: BlockToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n /**\r\n * Tool's settings passed from Editor\r\n *\r\n * @type {HeaderConfig}\r\n * @private\r\n */\r\n this._settings={placeholder:\"H3\"};\r\n\r\n /**\r\n * Block's data\r\n *\r\n * @type {HeaderData}\r\n * @private\r\n */\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * Main Block wrapper\r\n *\r\n * @type {HTMLElement}\r\n * @private\r\n */\r\n this._element = this.getTag();\r\n }\r\n /**\r\n * Styles\r\n */\r\n private get _CSS() {\r\n return {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-header',\r\n };\r\n }\r\n\r\n /**\r\n * Check if data is valid\r\n * \r\n * @param {any} data - data to check\r\n * @returns {data is HeaderData}\r\n * @private\r\n */\r\n isHeaderData(data: any): data is HeaderData {\r\n return (data as HeaderData).text !== undefined;\r\n }\r\n\r\n /**\r\n * Normalize input data\r\n *\r\n * @param {HeaderData} data - saved data to process\r\n *\r\n * @returns {HeaderData}\r\n * @private\r\n */\r\n normalizeData(data: HeaderData | {}): HeaderData {\r\n const newData: HeaderData = { text: '', level: this.defaultLevel.number };\r\n\r\n if (this.isHeaderData(data)) {\r\n newData.text = data.text || '';\r\n \r\n if (data.level !== undefined && !isNaN(parseInt(data.level.toString()))) {\r\n newData.level = parseInt(data.level.toString());\r\n }\r\n }\r\n\r\n return newData;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLHeadingElement}\r\n * @public\r\n */\r\n render(): HTMLHeadingElement {\r\n return this._element;\r\n }\r\n\r\n\r\n /**\r\n * Callback for Block's settings buttons\r\n *\r\n * @param {number} level - level to set\r\n */\r\n setLevel(level: number): void {\r\n this.data = {\r\n level: level,\r\n text: this.data.text,\r\n };\r\n }\r\n\r\n /**\r\n * Method that specified how to merge two Text blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * @param {HeaderData} data - saved data to merger with current block\r\n * @public\r\n */\r\n merge(data: HeaderData): void {\r\n this._element.insertAdjacentHTML('beforeend', data.text)\r\n }\r\n\r\n /**\r\n * Validate Text block data:\r\n * - check for emptiness\r\n *\r\n * @param {HeaderData} blockData — data received after saving\r\n * @returns {boolean} false if saved data is not correct, otherwise true\r\n * @public\r\n */\r\n validate(blockData: HeaderData): boolean {\r\n return blockData.text.trim() !== '';\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n *\r\n * @param {HTMLHeadingElement} toolsContent - Text tools rendered view\r\n * @returns {HeaderData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLHeadingElement): HeaderData {\r\n return {\r\n text: toolsContent.innerHTML,\r\n level: this.defaultLevel.number,\r\n };\r\n }\r\n\r\n /**\r\n * Allow Header to be converted to/from other blocks\r\n */\r\n static get conversionConfig() {\r\n return {\r\n export: 'text', // use 'text' property for other blocks\r\n import: 'text', // fill 'text' property from other block's export string\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer Rules\r\n */\r\n static get sanitize() {\r\n return {\r\n level: false,\r\n text: {},\r\n };\r\n }\r\n\r\n /**\r\n * Returns true to notify core that read-only is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get current Tools`s data\r\n *\r\n * @returns {HeaderData} Current data\r\n * @private\r\n */\r\n get data(): HeaderData {\r\n this._data.text = this._element.innerHTML;\r\n this._data.level = this.defaultLevel.number;\r\n \r\n return this._data;\r\n }\r\n\r\n /**\r\n * Store data in plugin:\r\n * - at the this._data property\r\n * - at the HTML\r\n *\r\n * @param {HeaderData} data — data to set\r\n * @private\r\n */\r\n set data(data: HeaderData) {\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * If level is set and block in DOM\r\n * then replace it to a new block\r\n */\r\n if (data.level !== undefined && this._element.parentNode) {\r\n /**\r\n * Create a new tag\r\n *\r\n * @type {HTMLHeadingElement}\r\n */\r\n const newHeader = this.getTag();\r\n\r\n /**\r\n * Save Block's content\r\n */\r\n newHeader.innerHTML = this._element.innerHTML;\r\n\r\n /**\r\n * Replace blocks\r\n */\r\n this._element.parentNode.replaceChild(newHeader, this._element);\r\n\r\n /**\r\n * Save new block to private variable\r\n *\r\n * @type {HTMLHeadingElement}\r\n * @private\r\n */\r\n this._element = newHeader;\r\n }\r\n\r\n /**\r\n * If data.text was passed then update block's content\r\n */\r\n if (data.text !== undefined) {\r\n this._element.innerHTML = this._data.text || '';\r\n }\r\n }\r\n\r\n /**\r\n * Get tag for target level\r\n * By default returns second-leveled header\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n getTag(): HTMLHeadingElement {\r\n const tag = this.createHeadingElement();\r\n this.setElementContent(tag);\r\n this.addStylesToElement(tag);\r\n this.setEditability(tag);\r\n this.addPlaceholder(tag);\r\n return tag;\r\n }\r\n\r\n /**\r\n * 创建标题元素\r\n * @returns {HTMLHeadingElement} 创建的HTML标题元素\r\n * @private\r\n */\r\n private createHeadingElement(): HTMLHeadingElement {\r\n return document.createElement(this.defaultLevel.tag) as HTMLHeadingElement;\r\n }\r\n\r\n /**\r\n * 设置元素内容\r\n * @param {HTMLHeadingElement} element - 要设置内容的HTML标题元素\r\n * @private\r\n */\r\n private setElementContent(element: HTMLHeadingElement): void {\r\n element.innerHTML = this._data.text || '';\r\n }\r\n\r\n /**\r\n * 为元素添加样式类\r\n * @param {HTMLHeadingElement} element - 要添加样式的HTML标题元素\r\n * @private\r\n */\r\n private addStylesToElement(element: HTMLHeadingElement): void {\r\n element.classList.add(this._CSS.wrapper);\r\n }\r\n\r\n /**\r\n * 设置元素可编辑属性\r\n * @param {HTMLHeadingElement} element - 要设置编辑属性的HTML标题元素\r\n * @private\r\n */\r\n private setEditability(element: HTMLHeadingElement): void {\r\n element.contentEditable = this.readOnly ? 'false' : 'true';\r\n }\r\n\r\n /**\r\n * 为元素添加占位符文本\r\n * @param {HTMLHeadingElement} element - 要添加占位符的HTML标题元素\r\n * @private\r\n */\r\n private addPlaceholder(element: HTMLHeadingElement): void {\r\n element.dataset.placeholder = this.api.i18n.t(this._settings.placeholder || '');\r\n }\r\n\r\n\r\n\r\n /**\r\n * Return default level\r\n *\r\n * @returns {level}\r\n */\r\n get defaultLevel(): Level {\r\n return {\r\n number: 3,\r\n tag: 'H3',\r\n svg: IconH3,\r\n };\r\n }\r\n\r\n\r\n\r\n\r\n /**\r\n * Handle H1-H6 tags on paste to substitute it with header Tool\r\n *\r\n * @param {PasteEvent} event - event with pasted content\r\n */\r\n onPaste(event: PasteEvent): void {\r\n const detail = event.detail;\r\n\r\n if ('data' in detail) {\r\n const content = detail.data as HTMLElement;\r\n this.data = {\r\n level: 3,\r\n text: content.innerHTML,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Used by Editor.js paste handling API.\r\n * Provides configuration to handle H1-H6 tags.\r\n *\r\n * @returns {{handler: (function(HTMLElement): {text: string}), tags: string[]}}\r\n */\r\n static get pasteConfig() {\r\n return {\r\n tags: ['H3'],\r\n };\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @returns {{icon: string, title: string}}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: IconH3,\r\n title: 'H3',\r\n };\r\n }\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\n\r\n\r\nimport { API, PasteEvent } from '@ebl-vue/editorjs';\r\nimport type { HeaderData, HeaderConfig, Level } from './types';\r\nimport type { BlockTool, BlockToolConstructorOptions } from '@ebl-vue/editorjs';\r\n\r\n\r\n\r\nimport { IconH4 } from '../../icons';\r\n\r\n/**\r\n * Header block for the Editor.js.\r\n *\r\n * @author CodeX (team@ifmo.su)\r\n * @copyright CodeX 2018\r\n * @license MIT\r\n * @version 2.0.0\r\n */\r\nexport default class H4 implements BlockTool {\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {{data: HeaderData, config: HeaderConfig, api: object}}\r\n * data — previously saved data\r\n * config - user config for Tool\r\n * api - Editor.js API\r\n * readOnly - read only mode flag\r\n */\r\n /**\r\n * Editor.js API\r\n * @private\r\n */\r\n private api: API;\r\n /**\r\n * Read-only mode flag\r\n * @private\r\n */\r\n private readOnly: boolean;\r\n /**\r\n * Tool's settings passed from Editor\r\n * @private\r\n */\r\n private _settings: HeaderConfig;\r\n /**\r\n * Block's data\r\n * @private\r\n */\r\n private _data: HeaderData;\r\n /**\r\n * Main Block wrapper\r\n * @private\r\n */\r\n private _element: HTMLHeadingElement;\r\n\r\n \r\n\r\n constructor({ data, config, api, readOnly }: BlockToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n /**\r\n * Tool's settings passed from Editor\r\n *\r\n * @type {HeaderConfig}\r\n * @private\r\n */\r\n this._settings={placeholder:\"H4\"};\r\n\r\n /**\r\n * Block's data\r\n *\r\n * @type {HeaderData}\r\n * @private\r\n */\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * Main Block wrapper\r\n *\r\n * @type {HTMLElement}\r\n * @private\r\n */\r\n this._element = this.getTag();\r\n }\r\n /**\r\n * Styles\r\n */\r\n private get _CSS() {\r\n return {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-header',\r\n };\r\n }\r\n\r\n /**\r\n * Check if data is valid\r\n * \r\n * @param {any} data - data to check\r\n * @returns {data is HeaderData}\r\n * @private\r\n */\r\n isHeaderData(data: any): data is HeaderData {\r\n return (data as HeaderData).text !== undefined;\r\n }\r\n\r\n /**\r\n * Normalize input data\r\n *\r\n * @param {HeaderData} data - saved data to process\r\n *\r\n * @returns {HeaderData}\r\n * @private\r\n */\r\n normalizeData(data: HeaderData | {}): HeaderData {\r\n const newData: HeaderData = { text: '', level: this.defaultLevel.number };\r\n\r\n if (this.isHeaderData(data)) {\r\n newData.text = data.text || '';\r\n \r\n if (data.level !== undefined && !isNaN(parseInt(data.level.toString()))) {\r\n newData.level = parseInt(data.level.toString());\r\n }\r\n }\r\n\r\n return newData;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLHeadingElement}\r\n * @public\r\n */\r\n render(): HTMLHeadingElement {\r\n return this._element;\r\n }\r\n\r\n\r\n /**\r\n * Callback for Block's settings buttons\r\n *\r\n * @param {number} level - level to set\r\n */\r\n setLevel(level: number): void {\r\n this.data = {\r\n level: level,\r\n text: this.data.text,\r\n };\r\n }\r\n\r\n /**\r\n * Method that specified how to merge two Text blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * @param {HeaderData} data - saved data to merger with current block\r\n * @public\r\n */\r\n merge(data: HeaderData): void {\r\n this._element.insertAdjacentHTML('beforeend', data.text)\r\n }\r\n\r\n /**\r\n * Validate Text block data:\r\n * - check for emptiness\r\n *\r\n * @param {HeaderData} blockData — data received after saving\r\n * @returns {boolean} false if saved data is not correct, otherwise true\r\n * @public\r\n */\r\n validate(blockData: HeaderData): boolean {\r\n return blockData.text.trim() !== '';\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n *\r\n * @param {HTMLHeadingElement} toolsContent - Text tools rendered view\r\n * @returns {HeaderData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLHeadingElement): HeaderData {\r\n return {\r\n text: toolsContent.innerHTML,\r\n level: this.defaultLevel.number,\r\n };\r\n }\r\n\r\n /**\r\n * Allow Header to be converted to/from other blocks\r\n */\r\n static get conversionConfig() {\r\n return {\r\n export: 'text', // use 'text' property for other blocks\r\n import: 'text', // fill 'text' property from other block's export string\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer Rules\r\n */\r\n static get sanitize() {\r\n return {\r\n level: false,\r\n text: {},\r\n };\r\n }\r\n\r\n /**\r\n * Returns true to notify core that read-only is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get current Tools`s data\r\n *\r\n * @returns {HeaderData} Current data\r\n * @private\r\n */\r\n get data(): HeaderData {\r\n this._data.text = this._element.innerHTML;\r\n this._data.level = this.defaultLevel.number;\r\n \r\n return this._data;\r\n }\r\n\r\n /**\r\n * Store data in plugin:\r\n * - at the this._data property\r\n * - at the HTML\r\n *\r\n * @param {HeaderData} data — data to set\r\n * @private\r\n */\r\n set data(data: HeaderData) {\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * If level is set and block in DOM\r\n * then replace it to a new block\r\n */\r\n if (data.level !== undefined && this._element.parentNode) {\r\n /**\r\n * Create a new tag\r\n *\r\n * @type {HTMLHeadingElement}\r\n */\r\n const newHeader = this.getTag();\r\n\r\n /**\r\n * Save Block's content\r\n */\r\n newHeader.innerHTML = this._element.innerHTML;\r\n\r\n /**\r\n * Replace blocks\r\n */\r\n this._element.parentNode.replaceChild(newHeader, this._element);\r\n\r\n /**\r\n * Save new block to private variable\r\n *\r\n * @type {HTMLHeadingElement}\r\n * @private\r\n */\r\n this._element = newHeader;\r\n }\r\n\r\n /**\r\n * If data.text was passed then update block's content\r\n */\r\n if (data.text !== undefined) {\r\n this._element.innerHTML = this._data.text || '';\r\n }\r\n }\r\n\r\n /**\r\n * Get tag for target level\r\n * By default returns second-leveled header\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n getTag(): HTMLHeadingElement {\r\n const tag = this.createHeadingElement();\r\n this.setElementContent(tag);\r\n this.addStylesToElement(tag);\r\n this.setEditability(tag);\r\n this.addPlaceholder(tag);\r\n return tag;\r\n }\r\n\r\n /**\r\n * 创建标题元素\r\n * @returns {HTMLHeadingElement} 创建的HTML标题元素\r\n * @private\r\n */\r\n private createHeadingElement(): HTMLHeadingElement {\r\n return document.createElement(this.defaultLevel.tag) as HTMLHeadingElement;\r\n }\r\n\r\n /**\r\n * 设置元素内容\r\n * @param {HTMLHeadingElement} element - 要设置内容的HTML标题元素\r\n * @private\r\n */\r\n private setElementContent(element: HTMLHeadingElement): void {\r\n element.innerHTML = this._data.text || '';\r\n }\r\n\r\n /**\r\n * 为元素添加样式类\r\n * @param {HTMLHeadingElement} element - 要添加样式的HTML标题元素\r\n * @private\r\n */\r\n private addStylesToElement(element: HTMLHeadingElement): void {\r\n element.classList.add(this._CSS.wrapper);\r\n }\r\n\r\n /**\r\n * 设置元素可编辑属性\r\n * @param {HTMLHeadingElement} element - 要设置编辑属性的HTML标题元素\r\n * @private\r\n */\r\n private setEditability(element: HTMLHeadingElement): void {\r\n element.contentEditable = this.readOnly ? 'false' : 'true';\r\n }\r\n\r\n /**\r\n * 为元素添加占位符文本\r\n * @param {HTMLHeadingElement} element - 要添加占位符的HTML标题元素\r\n * @private\r\n */\r\n private addPlaceholder(element: HTMLHeadingElement): void {\r\n element.dataset.placeholder = this.api.i18n.t(this._settings.placeholder || '');\r\n }\r\n\r\n\r\n\r\n /**\r\n * Return default level\r\n *\r\n * @returns {level}\r\n */\r\n get defaultLevel(): Level {\r\n return {\r\n number: 4,\r\n tag: 'H4',\r\n svg: IconH4,\r\n };\r\n }\r\n\r\n\r\n\r\n\r\n /**\r\n * Handle H1-H6 tags on paste to substitute it with header Tool\r\n *\r\n * @param {PasteEvent} event - event with pasted content\r\n */\r\n onPaste(event: PasteEvent): void {\r\n const detail = event.detail;\r\n\r\n if ('data' in detail) {\r\n const content = detail.data as HTMLElement;\r\n this.data = {\r\n level: 4,\r\n text: content.innerHTML,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Used by Editor.js paste handling API.\r\n * Provides configuration to handle H1-H6 tags.\r\n *\r\n * @returns {{handler: (function(HTMLElement): {text: string}), tags: string[]}}\r\n */\r\n static get pasteConfig() {\r\n return {\r\n tags: ['H4'],\r\n };\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @returns {{icon: string, title: string}}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: IconH4,\r\n title: 'H4',\r\n };\r\n }\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\n\r\n\r\nimport { API, PasteEvent } from '@ebl-vue/editorjs';\r\nimport type { HeaderData, HeaderConfig, Level } from './types';\r\nimport type { BlockTool, BlockToolConstructorOptions } from '@ebl-vue/editorjs';\r\n\r\n\r\nimport { IconH5 } from '../../icons';\r\n\r\n/**\r\n * Header block for the Editor.js.\r\n *\r\n * @author CodeX (team@ifmo.su)\r\n * @copyright CodeX 2018\r\n * @license MIT\r\n * @version 2.0.0\r\n */\r\nexport default class H5 implements BlockTool {\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {{data: HeaderData, config: HeaderConfig, api: object}}\r\n * data — previously saved data\r\n * config - user config for Tool\r\n * api - Editor.js API\r\n * readOnly - read only mode flag\r\n */\r\n /**\r\n * Editor.js API\r\n * @private\r\n */\r\n private api: API;\r\n /**\r\n * Read-only mode flag\r\n * @private\r\n */\r\n private readOnly: boolean;\r\n /**\r\n * Tool's settings passed from Editor\r\n * @private\r\n */\r\n private _settings: HeaderConfig;\r\n /**\r\n * Block's data\r\n * @private\r\n */\r\n private _data: HeaderData;\r\n /**\r\n * Main Block wrapper\r\n * @private\r\n */\r\n private _element: HTMLHeadingElement;\r\n\r\n \r\n\r\n constructor({ data, config, api, readOnly }: BlockToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n /**\r\n * Tool's settings passed from Editor\r\n *\r\n * @type {HeaderConfig}\r\n * @private\r\n */\r\n this._settings={placeholder:\"H5\"};\r\n\r\n /**\r\n * Block's data\r\n *\r\n * @type {HeaderData}\r\n * @private\r\n */\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * Main Block wrapper\r\n *\r\n * @type {HTMLElement}\r\n * @private\r\n */\r\n this._element = this.getTag();\r\n }\r\n /**\r\n * Styles\r\n */\r\n private get _CSS() {\r\n return {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-header',\r\n };\r\n }\r\n\r\n /**\r\n * Check if data is valid\r\n * \r\n * @param {any} data - data to check\r\n * @returns {data is HeaderData}\r\n * @private\r\n */\r\n isHeaderData(data: any): data is HeaderData {\r\n return (data as HeaderData).text !== undefined;\r\n }\r\n\r\n /**\r\n * Normalize input data\r\n *\r\n * @param {HeaderData} data - saved data to process\r\n *\r\n * @returns {HeaderData}\r\n * @private\r\n */\r\n normalizeData(data: HeaderData | {}): HeaderData {\r\n const newData: HeaderData = { text: '', level: this.defaultLevel.number };\r\n\r\n if (this.isHeaderData(data)) {\r\n newData.text = data.text || '';\r\n \r\n if (data.level !== undefined && !isNaN(parseInt(data.level.toString()))) {\r\n newData.level = parseInt(data.level.toString());\r\n }\r\n }\r\n\r\n return newData;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLHeadingElement}\r\n * @public\r\n */\r\n render(): HTMLHeadingElement {\r\n return this._element;\r\n }\r\n\r\n\r\n /**\r\n * Callback for Block's settings buttons\r\n *\r\n * @param {number} level - level to set\r\n */\r\n setLevel(level: number): void {\r\n this.data = {\r\n level: level,\r\n text: this.data.text,\r\n };\r\n }\r\n\r\n /**\r\n * Method that specified how to merge two Text blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * @param {HeaderData} data - saved data to merger with current block\r\n * @public\r\n */\r\n merge(data: HeaderData): void {\r\n this._element.insertAdjacentHTML('beforeend', data.text)\r\n }\r\n\r\n /**\r\n * Validate Text block data:\r\n * - check for emptiness\r\n *\r\n * @param {HeaderData} blockData — data received after saving\r\n * @returns {boolean} false if saved data is not correct, otherwise true\r\n * @public\r\n */\r\n validate(blockData: HeaderData): boolean {\r\n return blockData.text.trim() !== '';\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n *\r\n * @param {HTMLHeadingElement} toolsContent - Text tools rendered view\r\n * @returns {HeaderData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLHeadingElement): HeaderData {\r\n return {\r\n text: toolsContent.innerHTML,\r\n level: this.defaultLevel.number,\r\n };\r\n }\r\n\r\n /**\r\n * Allow Header to be converted to/from other blocks\r\n */\r\n static get conversionConfig() {\r\n return {\r\n export: 'text', // use 'text' property for other blocks\r\n import: 'text', // fill 'text' property from other block's export string\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer Rules\r\n */\r\n static get sanitize() {\r\n return {\r\n level: false,\r\n text: {},\r\n };\r\n }\r\n\r\n /**\r\n * Returns true to notify core that read-only is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get current Tools`s data\r\n *\r\n * @returns {HeaderData} Current data\r\n * @private\r\n */\r\n get data(): HeaderData {\r\n this._data.text = this._element.innerHTML;\r\n this._data.level = this.defaultLevel.number;\r\n \r\n return this._data;\r\n }\r\n\r\n /**\r\n * Store data in plugin:\r\n * - at the this._data property\r\n * - at the HTML\r\n *\r\n * @param {HeaderData} data — data to set\r\n * @private\r\n */\r\n set data(data: HeaderData) {\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * If level is set and block in DOM\r\n * then replace it to a new block\r\n */\r\n if (data.level !== undefined && this._element.parentNode) {\r\n /**\r\n * Create a new tag\r\n *\r\n * @type {HTMLHeadingElement}\r\n */\r\n const newHeader = this.getTag();\r\n\r\n /**\r\n * Save Block's content\r\n */\r\n newHeader.innerHTML = this._element.innerHTML;\r\n\r\n /**\r\n * Replace blocks\r\n */\r\n this._element.parentNode.replaceChild(newHeader, this._element);\r\n\r\n /**\r\n * Save new block to private variable\r\n *\r\n * @type {HTMLHeadingElement}\r\n * @private\r\n */\r\n this._element = newHeader;\r\n }\r\n\r\n /**\r\n * If data.text was passed then update block's content\r\n */\r\n if (data.text !== undefined) {\r\n this._element.innerHTML = this._data.text || '';\r\n }\r\n }\r\n\r\n /**\r\n * Get tag for target level\r\n * By default returns second-leveled header\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n getTag(): HTMLHeadingElement {\r\n const tag = this.createHeadingElement();\r\n this.setElementContent(tag);\r\n this.addStylesToElement(tag);\r\n this.setEditability(tag);\r\n this.addPlaceholder(tag);\r\n return tag;\r\n }\r\n\r\n /**\r\n * 创建标题元素\r\n * @returns {HTMLHeadingElement} 创建的HTML标题元素\r\n * @private\r\n */\r\n private createHeadingElement(): HTMLHeadingElement {\r\n return document.createElement(this.defaultLevel.tag) as HTMLHeadingElement;\r\n }\r\n\r\n /**\r\n * 设置元素内容\r\n * @param {HTMLHeadingElement} element - 要设置内容的HTML标题元素\r\n * @private\r\n */\r\n private setElementContent(element: HTMLHeadingElement): void {\r\n element.innerHTML = this._data.text || '';\r\n }\r\n\r\n /**\r\n * 为元素添加样式类\r\n * @param {HTMLHeadingElement} element - 要添加样式的HTML标题元素\r\n * @private\r\n */\r\n private addStylesToElement(element: HTMLHeadingElement): void {\r\n element.classList.add(this._CSS.wrapper);\r\n }\r\n\r\n /**\r\n * 设置元素可编辑属性\r\n * @param {HTMLHeadingElement} element - 要设置编辑属性的HTML标题元素\r\n * @private\r\n */\r\n private setEditability(element: HTMLHeadingElement): void {\r\n element.contentEditable = this.readOnly ? 'false' : 'true';\r\n }\r\n\r\n /**\r\n * 为元素添加占位符文本\r\n * @param {HTMLHeadingElement} element - 要添加占位符的HTML标题元素\r\n * @private\r\n */\r\n private addPlaceholder(element: HTMLHeadingElement): void {\r\n element.dataset.placeholder = this.api.i18n.t(this._settings.placeholder || '');\r\n }\r\n\r\n\r\n\r\n /**\r\n * Return default level\r\n *\r\n * @returns {level}\r\n */\r\n get defaultLevel(): Level {\r\n return {\r\n number: 5,\r\n tag: 'H5',\r\n svg: IconH5,\r\n };\r\n }\r\n\r\n\r\n\r\n\r\n /**\r\n * Handle H1-H6 tags on paste to substitute it with header Tool\r\n *\r\n * @param {PasteEvent} event - event with pasted content\r\n */\r\n onPaste(event: PasteEvent): void {\r\n const detail = event.detail;\r\n\r\n if ('data' in detail) {\r\n const content = detail.data as HTMLElement;\r\n this.data = {\r\n level: 5,\r\n text: content.innerHTML,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Used by Editor.js paste handling API.\r\n * Provides configuration to handle H1-H6 tags.\r\n *\r\n * @returns {{handler: (function(HTMLElement): {text: string}), tags: string[]}}\r\n */\r\n static get pasteConfig() {\r\n return {\r\n tags: ['H5'],\r\n };\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @returns {{icon: string, title: string}}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: IconH5,\r\n title: 'H5',\r\n };\r\n }\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\n\r\n\r\nimport { API, PasteEvent } from '@ebl-vue/editorjs';\r\nimport type { HeaderData, HeaderConfig, Level } from './types';\r\nimport type { BlockTool, BlockToolConstructorOptions } from '@ebl-vue/editorjs';\r\n\r\n\r\nimport { IconH6 } from '../../icons';\r\n\r\n/**\r\n * Header block for the Editor.js.\r\n *\r\n * @author CodeX (team@ifmo.su)\r\n * @copyright CodeX 2018\r\n * @license MIT\r\n * @version 2.0.0\r\n */\r\nexport default class H6 implements BlockTool {\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {{data: HeaderData, config: HeaderConfig, api: object}}\r\n * data — previously saved data\r\n * config - user config for Tool\r\n * api - Editor.js API\r\n * readOnly - read only mode flag\r\n */\r\n /**\r\n * Editor.js API\r\n * @private\r\n */\r\n private api: API;\r\n /**\r\n * Read-only mode flag\r\n * @private\r\n */\r\n private readOnly: boolean;\r\n /**\r\n * Tool's settings passed from Editor\r\n * @private\r\n */\r\n private _settings: HeaderConfig;\r\n /**\r\n * Block's data\r\n * @private\r\n */\r\n private _data: HeaderData;\r\n /**\r\n * Main Block wrapper\r\n * @private\r\n */\r\n private _element: HTMLHeadingElement;\r\n\r\n \r\n\r\n constructor({ data, config, api, readOnly }: BlockToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n /**\r\n * Tool's settings passed from Editor\r\n *\r\n * @type {HeaderConfig}\r\n * @private\r\n */\r\n this._settings={placeholder:\"H6\"};\r\n\r\n /**\r\n * Block's data\r\n *\r\n * @type {HeaderData}\r\n * @private\r\n */\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * Main Block wrapper\r\n *\r\n * @type {HTMLElement}\r\n * @private\r\n */\r\n this._element = this.getTag();\r\n }\r\n /**\r\n * Styles\r\n */\r\n private get _CSS() {\r\n return {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-header',\r\n };\r\n }\r\n\r\n /**\r\n * Check if data is valid\r\n * \r\n * @param {any} data - data to check\r\n * @returns {data is HeaderData}\r\n * @private\r\n */\r\n isHeaderData(data: any): data is HeaderData {\r\n return (data as HeaderData).text !== undefined;\r\n }\r\n\r\n /**\r\n * Normalize input data\r\n *\r\n * @param {HeaderData} data - saved data to process\r\n *\r\n * @returns {HeaderData}\r\n * @private\r\n */\r\n normalizeData(data: HeaderData | {}): HeaderData {\r\n const newData: HeaderData = { text: '', level: this.defaultLevel.number };\r\n\r\n if (this.isHeaderData(data)) {\r\n newData.text = data.text || '';\r\n \r\n if (data.level !== undefined && !isNaN(parseInt(data.level.toString()))) {\r\n newData.level = parseInt(data.level.toString());\r\n }\r\n }\r\n\r\n return newData;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLHeadingElement}\r\n * @public\r\n */\r\n render(): HTMLHeadingElement {\r\n return this._element;\r\n }\r\n\r\n\r\n /**\r\n * Callback for Block's settings buttons\r\n *\r\n * @param {number} level - level to set\r\n */\r\n setLevel(level: number): void {\r\n this.data = {\r\n level: level,\r\n text: this.data.text,\r\n };\r\n }\r\n\r\n /**\r\n * Method that specified how to merge two Text blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * @param {HeaderData} data - saved data to merger with current block\r\n * @public\r\n */\r\n merge(data: HeaderData): void {\r\n this._element.insertAdjacentHTML('beforeend', data.text)\r\n }\r\n\r\n /**\r\n * Validate Text block data:\r\n * - check for emptiness\r\n *\r\n * @param {HeaderData} blockData — data received after saving\r\n * @returns {boolean} false if saved data is not correct, otherwise true\r\n * @public\r\n */\r\n validate(blockData: HeaderData): boolean {\r\n return blockData.text.trim() !== '';\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n *\r\n * @param {HTMLHeadingElement} toolsContent - Text tools rendered view\r\n * @returns {HeaderData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLHeadingElement): HeaderData {\r\n return {\r\n text: toolsContent.innerHTML,\r\n level: this.defaultLevel.number,\r\n };\r\n }\r\n\r\n /**\r\n * Allow Header to be converted to/from other blocks\r\n */\r\n static get conversionConfig() {\r\n return {\r\n export: 'text', // use 'text' property for other blocks\r\n import: 'text', // fill 'text' property from other block's export string\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer Rules\r\n */\r\n static get sanitize() {\r\n return {\r\n level: false,\r\n text: {},\r\n };\r\n }\r\n\r\n /**\r\n * Returns true to notify core that read-only is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get current Tools`s data\r\n *\r\n * @returns {HeaderData} Current data\r\n * @private\r\n */\r\n get data(): HeaderData {\r\n this._data.text = this._element.innerHTML;\r\n this._data.level = this.defaultLevel.number;\r\n \r\n return this._data;\r\n }\r\n\r\n /**\r\n * Store data in plugin:\r\n * - at the this._data property\r\n * - at the HTML\r\n *\r\n * @param {HeaderData} data — data to set\r\n * @private\r\n */\r\n set data(data: HeaderData) {\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * If level is set and block in DOM\r\n * then replace it to a new block\r\n */\r\n if (data.level !== undefined && this._element.parentNode) {\r\n /**\r\n * Create a new tag\r\n *\r\n * @type {HTMLHeadingElement}\r\n */\r\n const newHeader = this.getTag();\r\n\r\n /**\r\n * Save Block's content\r\n */\r\n newHeader.innerHTML = this._element.innerHTML;\r\n\r\n /**\r\n * Replace blocks\r\n */\r\n this._element.parentNode.replaceChild(newHeader, this._element);\r\n\r\n /**\r\n * Save new block to private variable\r\n *\r\n * @type {HTMLHeadingElement}\r\n * @private\r\n */\r\n this._element = newHeader;\r\n }\r\n\r\n /**\r\n * If data.text was passed then update block's content\r\n */\r\n if (data.text !== undefined) {\r\n this._element.innerHTML = this._data.text || '';\r\n }\r\n }\r\n\r\n /**\r\n * Get tag for target level\r\n * By default returns second-leveled header\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n getTag(): HTMLHeadingElement {\r\n const tag = this.createHeadingElement();\r\n this.setElementContent(tag);\r\n this.addStylesToElement(tag);\r\n this.setEditability(tag);\r\n this.addPlaceholder(tag);\r\n return tag;\r\n }\r\n\r\n /**\r\n * 创建标题元素\r\n * @returns {HTMLHeadingElement} 创建的HTML标题元素\r\n * @private\r\n */\r\n private createHeadingElement(): HTMLHeadingElement {\r\n return document.createElement(this.defaultLevel.tag) as HTMLHeadingElement;\r\n }\r\n\r\n /**\r\n * 设置元素内容\r\n * @param {HTMLHeadingElement} element - 要设置内容的HTML标题元素\r\n * @private\r\n */\r\n private setElementContent(element: HTMLHeadingElement): void {\r\n element.innerHTML = this._data.text || '';\r\n }\r\n\r\n /**\r\n * 为元素添加样式类\r\n * @param {HTMLHeadingElement} element - 要添加样式的HTML标题元素\r\n * @private\r\n */\r\n private addStylesToElement(element: HTMLHeadingElement): void {\r\n element.classList.add(this._CSS.wrapper);\r\n }\r\n\r\n /**\r\n * 设置元素可编辑属性\r\n * @param {HTMLHeadingElement} element - 要设置编辑属性的HTML标题元素\r\n * @private\r\n */\r\n private setEditability(element: HTMLHeadingElement): void {\r\n element.contentEditable = this.readOnly ? 'false' : 'true';\r\n }\r\n\r\n /**\r\n * 为元素添加占位符文本\r\n * @param {HTMLHeadingElement} element - 要添加占位符的HTML标题元素\r\n * @private\r\n */\r\n private addPlaceholder(element: HTMLHeadingElement): void {\r\n element.dataset.placeholder = this.api.i18n.t(this._settings.placeholder || '');\r\n }\r\n\r\n\r\n\r\n /**\r\n * Return default level\r\n *\r\n * @returns {level}\r\n */\r\n get defaultLevel(): Level {\r\n return {\r\n number: 6,\r\n tag: 'H6',\r\n svg: IconH6,\r\n };\r\n }\r\n\r\n\r\n\r\n\r\n /**\r\n * Handle H1-H6 tags on paste to substitute it with header Tool\r\n *\r\n * @param {PasteEvent} event - event with pasted content\r\n */\r\n onPaste(event: PasteEvent): void {\r\n const detail = event.detail;\r\n\r\n if ('data' in detail) {\r\n const content = detail.data as HTMLElement;\r\n this.data = {\r\n level: 6,\r\n text: content.innerHTML,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Used by Editor.js paste handling API.\r\n * Provides configuration to handle H1-H6 tags.\r\n *\r\n * @returns {{handler: (function(HTMLElement): {text: string}), tags: string[]}}\r\n */\r\n static get pasteConfig() {\r\n return {\r\n tags: ['H6'],\r\n };\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @returns {{icon: string, title: string}}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: IconH6,\r\n title: 'H6',\r\n \r\n };\r\n }\r\n}\r\n","import \"./index.css\"\r\nimport type { API, BlockTune, ToolConfig } from \"@ebl-vue/editorjs/types\";\r\nimport { IconAlignLeft,IconAlignCenter,IconAlignRight } from \"../../icons\";\r\n\r\ninterface ConstructorArgs {\r\n data: AlignmentData;\r\n config?: ToolConfig;\r\n api: API;\r\n block?: any;\r\n}\r\nexport interface AlignmentData {\r\n text?: string;\r\n alignment: string\r\n}\r\n\r\nexport default class BlockAlignment implements BlockTune{\r\n private settings: ToolConfig;\r\n private block: any;\r\n private api: API;\r\n private data: AlignmentData;\r\n private alignmentSettings: any[];\r\n private _CSS: any;\r\n private wrapper: HTMLElement | undefined;\r\n\r\n\r\n static get DEFAULT_ALIGNMENT() {\r\n return 'left';\r\n }\r\n\r\n static get isTune() {\r\n return true;\r\n }\r\n\r\n getAlignment() {\r\n if (!!this.settings?.blocks && this.settings.blocks.hasOwnProperty(this.block.name)) {\r\n return this.settings.blocks[this.block.name]\r\n }\r\n if (!!this.settings?.default) {\r\n return this.settings.default\r\n }\r\n return BlockAlignment.DEFAULT_ALIGNMENT\r\n }\r\n\r\n constructor({ api, data, config, block }: ConstructorArgs) {\r\n this.api = api;\r\n this.block = block;\r\n\r\n this.settings = config;\r\n this.data = data || { alignment: this.getAlignment() }\r\n this.alignmentSettings = [\r\n {\r\n name: 'left',\r\n icon: IconAlignLeft\r\n },\r\n {\r\n name: 'center',\r\n icon: IconAlignCenter\r\n },\r\n {\r\n name: 'right',\r\n icon: IconAlignRight\r\n }\r\n ];\r\n this._CSS = {\r\n alignment: {\r\n left: 'ce-tune-alignment--left',\r\n center: 'ce-tune-alignment--center',\r\n right: 'ce-tune-alignment--right',\r\n }\r\n }\r\n }\r\n\r\n\r\n wrap(blockContent: HTMLElement) {\r\n this.wrapper = document.createElement(\"div\");\r\n this.wrapper!.classList.toggle(this._CSS.alignment[this.data.alignment])\r\n this.wrapper!.append(blockContent)\r\n return this.wrapper\r\n }\r\n\r\n\r\n render() {\r\n const wrapper = document.createElement(\"div\");\r\n this.alignmentSettings.map(align => {\r\n const button = document.createElement('button');\r\n button.classList.add(this.api.styles.settingsButton);\r\n button.innerHTML = align.icon;\r\n button.type = 'button';\r\n\r\n button.classList.toggle(this.api.styles.settingsButtonActive, align.name === this.data.alignment);\r\n const buttonTooltip = this.api.i18n.t(align.name + \" align\");\r\n this.api.tooltip.onHover(button, buttonTooltip, {\r\n placement: 'top',\r\n });\r\n wrapper.appendChild(button);\r\n return button\r\n }).forEach((element, index, elements) => {\r\n element.addEventListener('click', () => {\r\n this.data = {\r\n alignment: this.alignmentSettings[index].name\r\n }\r\n elements.forEach((el, i) => {\r\n const { name } = this.alignmentSettings[i];\r\n el.classList.toggle(this.api.styles.settingsButtonActive, name === this.data.alignment);\r\n this.wrapper!.classList.toggle(this._CSS.alignment[name], name === this.data.alignment)\r\n });\r\n });\r\n });\r\n return wrapper;\r\n }\r\n\r\n\r\n save() {\r\n return this.data;\r\n }\r\n}\r\n\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\n\r\nimport makeFragment from './utils/makeFragment';\r\nimport type { BlockToolConstructorOptions } from '@ebl-vue/editorjs';\r\nimport {IconText} from \"../../icons\";\r\nexport type ToolConstructorOptions = BlockToolConstructorOptions<ParagraphData>;\r\n\r\n\r\nimport type {\r\n API,\r\n ConversionConfig,\r\n HTMLPasteEvent,\r\n PasteConfig,\r\n SanitizerConfig,\r\n ToolConfig,\r\n ToolboxConfig,\r\n} from '@ebl-vue/editorjs';\r\n\r\n/**\r\n * Base Paragraph Block for the Editor.js.\r\n * Represents a regular text block\r\n *\r\n * @author CodeX (team@codex.so)\r\n * @copyright CodeX 2018\r\n * @license The MIT License (MIT)\r\n */\r\n\r\n/**\r\n * @typedef {object} ParagraphConfig\r\n * @property {string} placeholder - placeholder for the empty paragraph\r\n * @property {boolean} preserveBlank - Whether or not to keep blank paragraphs when saving editor data\r\n */\r\nexport interface ParagraphConfig extends ToolConfig {\r\n /**\r\n * Placeholder for the empty paragraph\r\n */\r\n placeholder?: string;\r\n\r\n /**\r\n * Whether or not to keep blank paragraphs when saving editor data\r\n */\r\n preserveBlank?: boolean;\r\n}\r\n\r\n/**\r\n * @typedef {object} ParagraphData\r\n * @description Tool's input and output data format\r\n * @property {string} text — Paragraph's content. Can include HTML tags: <a><b><i>\r\n */\r\nexport interface ParagraphData {\r\n /**\r\n * Paragraph's content\r\n */\r\n text: string;\r\n}\r\n\r\n/**\r\n * @typedef {object} ParagraphParams\r\n * @description Constructor params for the Paragraph tool, use to pass initial data and settings\r\n * @property {ParagraphData} data - Preload data for the paragraph.\r\n * @property {ParagraphConfig} config - The configuration for the paragraph.\r\n * @property {API} api - The Editor.js API.\r\n * @property {boolean} readOnly - Is paragraph is read-only.\r\n */\r\n// interface ParagraphParams {\r\n// /**\r\n// * Initial data for the paragraph\r\n// */\r\n// data: ParagraphData;\r\n// /**\r\n// * Paragraph tool configuration\r\n// */\r\n// config: ParagraphConfig;\r\n// /**\r\n// * Editor.js API\r\n// */\r\n// api: API;\r\n// /**\r\n// * Is paragraph read-only.\r\n// */\r\n// readOnly: boolean;\r\n// }\r\n\r\n/**\r\n * @typedef {object} ParagraphCSS\r\n * @description CSS classes names\r\n * @property {string} block - Editor.js CSS Class for block\r\n * @property {string} wrapper - Paragraph CSS Class\r\n */\r\ninterface ParagraphCSS {\r\n /**\r\n * Editor.js CSS Class for block\r\n */\r\n block: string;\r\n /**\r\n * Paragraph CSS Class\r\n */\r\n wrapper: string;\r\n}\r\n\r\nexport default class Paragraph {\r\n /**\r\n * Default placeholder for Paragraph Tool\r\n *\r\n * @returns {string}\r\n * @class\r\n */\r\n static get DEFAULT_PLACEHOLDER() {\r\n return '';\r\n }\r\n\r\n /**\r\n * The Editor.js API\r\n */\r\n api: API;\r\n\r\n /**\r\n * Is Paragraph Tool read-only\r\n */\r\n readOnly: boolean;\r\n\r\n /**\r\n * Paragraph Tool's CSS classes\r\n */\r\n private _CSS: ParagraphCSS;\r\n\r\n /**\r\n * Placeholder for Paragraph Tool\r\n */\r\n private _placeholder: string;\r\n\r\n /**\r\n * Paragraph's data\r\n */\r\n private _data: ParagraphData;\r\n\r\n /**\r\n * Paragraph's main Element\r\n */\r\n private _element: HTMLDivElement | null;\r\n\r\n /**\r\n * Whether or not to keep blank paragraphs when saving editor data\r\n */\r\n private _preserveBlank: boolean;\r\n\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {object} params - constructor params\r\n * @param {ParagraphData} params.data - previously saved data\r\n * @param {ParagraphConfig} params.config - user config for Tool\r\n * @param {object} params.api - editor.js api\r\n * @param {boolean} readOnly - read only mode flag\r\n */\r\n constructor({ data, config, api, readOnly }: ToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n this._CSS = {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-paragraph',\r\n };\r\n\r\n if (!this.readOnly) {\r\n this.onKeyUp = this.onKeyUp.bind(this);\r\n }\r\n\r\n /**\r\n * Placeholder for paragraph if it is first Block\r\n *\r\n * @type {string}\r\n */\r\n this._placeholder = config.placeholder\r\n ? config.placeholder\r\n : Paragraph.DEFAULT_PLACEHOLDER;\r\n this._data = data ?? {};\r\n this._element = null;\r\n this._preserveBlank = config.preserveBlank ?? false;\r\n }\r\n\r\n /**\r\n * Check if text content is empty and set empty string to inner html.\r\n * We need this because some browsers (e.g. Safari) insert <br> into empty contenteditanle elements\r\n *\r\n * @param {KeyboardEvent} e - key up event\r\n */\r\n onKeyUp(e: KeyboardEvent): void {\r\n if (e.code !== 'Backspace' && e.code !== 'Delete') {\r\n return;\r\n }\r\n\r\n if (!this._element) {\r\n return;\r\n }\r\n\r\n const { textContent } = this._element;\r\n\r\n if (textContent === '') {\r\n this._element.innerHTML = '';\r\n }\r\n }\r\n\r\n /**\r\n * Create Tool's view\r\n *\r\n * @returns {HTMLDivElement}\r\n * @private\r\n */\r\n drawView(): HTMLDivElement {\r\n const div = document.createElement('DIV');\r\n\r\n div.classList.add(this._CSS.wrapper, this._CSS.block);\r\n div.contentEditable = 'false';\r\n div.dataset.placeholderActive = this.api.i18n.t(this._placeholder);\r\n\r\n if (this._data.text) {\r\n div.innerHTML = this._data.text;\r\n }\r\n\r\n if (!this.readOnly) {\r\n div.contentEditable = 'true';\r\n div.addEventListener('keyup', this.onKeyUp);\r\n }\r\n\r\n /**\r\n * bypass property 'align' required in html div element\r\n */\r\n return div as HTMLDivElement;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLDivElement}\r\n */\r\n render(): HTMLDivElement {\r\n this._element = this.drawView();\r\n\r\n return this._element;\r\n }\r\n\r\n\r\n\r\n /**\r\n * Method that specified how to merge two Text blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * @param {ParagraphData} data\r\n * @public\r\n */\r\n merge(data: ParagraphData): void {\r\n if (!this._element) {\r\n return;\r\n }\r\n\r\n this._data.text += data.text;\r\n\r\n /**\r\n * We use appendChild instead of innerHTML to keep the links of the existing nodes\r\n * (for example, shadow caret)\r\n */\r\n const fragment = makeFragment(data.text);\r\n\r\n this._element.appendChild(fragment);\r\n\r\n this._element.normalize();\r\n }\r\n\r\n /**\r\n * Validate Paragraph block data:\r\n * - check for emptiness\r\n *\r\n * @param {ParagraphData} savedData — data received after saving\r\n * @returns {boolean} false if saved data is not correct, otherwise true\r\n * @public\r\n */\r\n validate(savedData: ParagraphData): boolean {\r\n if (savedData.text.trim() === '' && !this._preserveBlank) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n *\r\n * @param {HTMLDivElement} toolsContent - Paragraph tools rendered view\r\n * @returns {ParagraphData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLDivElement): ParagraphData {\r\n return {\r\n text: toolsContent.innerHTML,\r\n };\r\n }\r\n\r\n /**\r\n * On paste callback fired from Editor.\r\n *\r\n * @param {HTMLPasteEvent} event - event with pasted data\r\n */\r\n onPaste(event: HTMLPasteEvent): void {\r\n const data = {\r\n text: event.detail.data.innerHTML,\r\n };\r\n\r\n this._data = data;\r\n\r\n /**\r\n * We use requestAnimationFrame for performance purposes\r\n */\r\n window.requestAnimationFrame(() => {\r\n if (!this._element) {\r\n return;\r\n }\r\n this._element.innerHTML = this._data.text || '';\r\n });\r\n }\r\n\r\n /**\r\n * Enable Conversion Toolbar. Paragraph can be converted to/from other tools\r\n * @returns {ConversionConfig}\r\n */\r\n static get conversionConfig(): ConversionConfig {\r\n return {\r\n export: 'text', // to convert Paragraph to other block, use 'text' property of saved data\r\n import: 'text', // to covert other block's exported string to Paragraph, fill 'text' property of tool data\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer rules\r\n * @returns {SanitizerConfig} - Edtior.js sanitizer config\r\n */\r\n static get sanitize(): SanitizerConfig {\r\n return {\r\n text: {\r\n br: true,\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Returns true to notify the core that read-only mode is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Used by Editor paste handling API.\r\n * Provides configuration to handle P tags.\r\n *\r\n * @returns {PasteConfig} - Paragraph Paste Setting\r\n */\r\n static get pasteConfig(): PasteConfig {\r\n return {\r\n tags: ['P'],\r\n };\r\n }\r\n\r\n /**\r\n * Icon and title for displaying at the Toolbox\r\n *\r\n * @returns {ToolboxConfig} - Paragraph Toolbox Setting\r\n */\r\n static get toolbox(): ToolboxConfig {\r\n return {\r\n icon: IconText,\r\n title: 'Text',\r\n\r\n };\r\n }\r\n}\r\n","/**\r\n * Create a DocumentFragment and fill it with HTML from a string\r\n *\r\n * @param {string} htmlString - A string of valid HTML\r\n * @returns {DocumentFragment}\r\n */\r\nexport default function makeFragment(htmlString: string): DocumentFragment {\r\n const tempDiv = document.createElement('div');\r\n\r\n tempDiv.innerHTML = htmlString.trim();\r\n\r\n const fragment = document.createDocumentFragment();\r\n\r\n fragment.append(...Array.from(tempDiv.childNodes));\r\n\r\n return fragment;\r\n}\r\n","//https://github.com/yudaapratama/editorjs-shiki\r\nimport './index.css';\r\nimport type { API, BlockTool, BlockToolConstructorOptions, BlockToolData, PasteConfig, PasteEvent, SanitizerConfig, ToolboxConfig } from '@ebl-vue/editorjs';\r\nimport { codeToHtml, bundledLanguagesInfo as languages } from 'shiki'\r\nimport { getLineStartPosition } from './utils/string';\r\nimport { IconCode ,IconCopy} from \"../../icons\";\r\n\r\n/**\r\n * CodeTool for Editor.js\r\n * @version 1.0.0\r\n * @license MIT\r\n */\r\n\r\n/**\r\n * Data structure for CodeTool's data\r\n */\r\nexport type CodeData = BlockToolData<{\r\n /**\r\n * The code content input by the user\r\n */\r\n code: string;\r\n lang: string;\r\n theme: string;\r\n}>;\r\n\r\n/**\r\n * Configuration options for the CodeTool provided by the user\r\n */\r\nexport interface CodeConfig {\r\n /**\r\n * Placeholder text to display in the input field when it's empty\r\n */\r\n placeholder: string;\r\n}\r\n\r\n/**\r\n * Defines the CSS class names used by CodeTool for styling its elements\r\n */\r\ninterface CodeToolCSS {\r\n /** Block Styling from Editor.js API */\r\n baseClass: string;\r\n /** Input Styling from Editor.js API */\r\n input: string;\r\n /** Wrapper styling */\r\n wrapper: string;\r\n /** Textarea styling */\r\n textarea: string;\r\n /** Span styling */\r\n span: string;\r\n /** Selector Language styling */\r\n selectorLanguage: string;\r\n /** Selector Theme styling */\r\n selectorTheme: string;\r\n}\r\n\r\n/**\r\n * Holds references to the DOM elements used by CodeTool\r\n */\r\ninterface CodeToolNodes {\r\n /** Main container or Wrapper for CodeTool */\r\n holder: HTMLDivElement | null;\r\n /** Textarea where user inputs their code */\r\n textarea: HTMLTextAreaElement | null;\r\n}\r\n\r\n/**\r\n * Options passed to the constructor of a block tool\r\n */\r\nexport type CodeToolConstructorOptions = BlockToolConstructorOptions<CodeData>;\r\n\r\n/**\r\n * Code Tool for the Editor.js allows to include code examples in your articles.\r\n */\r\nexport default class CodeTool implements BlockTool {\r\n /**\r\n * API provided by Editor.js for interacting with the editor's core functionality\r\n */\r\n private api: API;\r\n /**\r\n * Indicates whether the editor is in read-only mode, preventing modifications\r\n */\r\n private readOnly: boolean;\r\n /**\r\n * Placeholder text displayed when there is no code content\r\n */\r\n private placeholder: string;\r\n /**\r\n * Collection of CSS class names used by CodeTool for styling its elements\r\n */\r\n private CSS: CodeToolCSS;\r\n /**\r\n * DOM nodes related to the CodeTool, including containers and other elements\r\n */\r\n private nodes: CodeToolNodes;\r\n /**\r\n * Stores the current data (code and other related properties) for the CodeTool\r\n */\r\n private _data!: CodeData;\r\n /**\r\n * Default language for the CodeTool\r\n */\r\n private _selectorLanguage: string = '';\r\n /**\r\n * Default theme for the CodeTool\r\n */\r\n private _selectorTheme: string = '';\r\n /**\r\n * Notify core that read-only mode is supported\r\n * @returns true if read-only mode is supported\r\n */\r\n public static get isReadOnlySupported(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Allows pressing Enter key to create line breaks inside the CodeTool textarea\r\n * This enables multi-line input within the code editor.\r\n * @returns true if line breaks are allowed in the textarea\r\n */\r\n public static get enableLineBreaks(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n * @param options - tool constricting options\r\n * @param options.data — previously saved plugin code\r\n * @param options.config - user config for Tool\r\n * @param options.api - Editor.js API\r\n * @param options.readOnly - read only mode flag\r\n */\r\n constructor({ data, config, api, readOnly }: CodeToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n this.placeholder = this.api.i18n.t(config.placeholder as string || CodeTool.DEFAULT_PLACEHOLDER);\r\n\r\n this._selectorLanguage = data.lang || config.lang || CodeTool.DEFAULT_LANGUAGE\r\n this._selectorTheme = data.theme || config.theme || CodeTool.DEFAULT_THEME\r\n\r\n this.CSS = {\r\n baseClass: this.api.styles.block,\r\n input: this.api.styles.input,\r\n wrapper: 'ce-editorjs-x-shiki',\r\n textarea: 'ce-editorjs-x-shiki__textarea',\r\n span: 'ce-editorjs-x-shiki__span',\r\n selectorLanguage: 'ce-editorjs-x-shiki__selector-language',\r\n selectorTheme: 'ce-editorjs-x-shiki__selector-theme',\r\n };\r\n\r\n this.nodes = {\r\n holder: null,\r\n textarea: null,\r\n };\r\n\r\n this.data = {\r\n code: data.code ?? '',\r\n lang: this._selectorLanguage,\r\n theme: this._selectorTheme,\r\n };\r\n\r\n this.nodes.holder = this.drawView()\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n * @returns this.nodes.holder - Code's wrapper\r\n */\r\n public render(): HTMLDivElement {\r\n return this.nodes.holder!;\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n * @param codeWrapper - CodeTool's wrapper, containing textarea with code\r\n * @returns - saved plugin code\r\n */\r\n public save(codeWrapper: HTMLDivElement): CodeData {\r\n return {\r\n code: codeWrapper.querySelector('textarea')!.value,\r\n lang: this._selectorLanguage,\r\n theme: this._selectorTheme\r\n };\r\n }\r\n\r\n /**\r\n * onPaste callback fired from Editor`s core\r\n * @param event - event with pasted content\r\n */\r\n public onPaste(event: PasteEvent): void {\r\n const detail = event.detail;\r\n\r\n if ('data' in detail) {\r\n const content = detail.data as string;\r\n\r\n this.data = {\r\n code: content || '',\r\n lang: this._selectorLanguage,\r\n theme: this._selectorTheme\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Returns Tool`s data from private property\r\n * @returns\r\n */\r\n public get data(): CodeData {\r\n return this._data;\r\n }\r\n\r\n /**\r\n * Set Tool`s data to private property and update view\r\n * @param data - saved tool data\r\n */\r\n public set data(data: CodeData) {\r\n this._data = data;\r\n\r\n if (this.nodes.textarea) {\r\n this.nodes.textarea.value = data.code;\r\n }\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings.\r\n * Provides the icon and title to display in the toolbox for the CodeTool.\r\n * @returns An object containing:\r\n * - icon: SVG representation of the Tool's icon\r\n * - title: Title to show in the toolbox\r\n */\r\n public static get toolbox(): ToolboxConfig {\r\n return {\r\n icon: IconCode,\r\n title: 'Code',\r\n };\r\n }\r\n\r\n /**\r\n * Default placeholder for CodeTool's textarea\r\n * @returns\r\n */\r\n public static get DEFAULT_PLACEHOLDER(): string {\r\n return 'Enter your code';\r\n }\r\n\r\n /**\r\n * Default language for CodeTool's textarea\r\n * @returns\r\n */\r\n public static get DEFAULT_LANGUAGE(): string {\r\n return 'javascript';\r\n }\r\n\r\n /**\r\n * Default theme for CodeTool's textarea\r\n * @returns\r\n */\r\n public static get DEFAULT_THEME(): string {\r\n return 'vitesse-dark';\r\n }\r\n\r\n /**\r\n * Used by Editor.js paste handling API.\r\n * Provides configuration to handle CODE tag.\r\n * @returns\r\n */\r\n public static get pasteConfig(): PasteConfig {\r\n return {\r\n tags: ['pre'],\r\n };\r\n }\r\n\r\n /**\r\n * Automatic sanitize config\r\n * @returns\r\n */\r\n public static get sanitize(): SanitizerConfig {\r\n return {\r\n code: true, // Allow HTML tags\r\n };\r\n }\r\n\r\n /**\r\n * Handles Tab key pressing (adds/removes indentations)\r\n * @param event - keydown\r\n */\r\n private tabHandler(event: KeyboardEvent): void {\r\n /**\r\n * Prevent editor.js tab handler\r\n */\r\n event.stopPropagation();\r\n\r\n /**\r\n * Prevent native tab behaviour\r\n */\r\n event.preventDefault();\r\n\r\n const textarea = event.target as HTMLTextAreaElement;\r\n const isShiftPressed = event.shiftKey;\r\n const caretPosition = textarea.selectionStart;\r\n const value = textarea.value;\r\n const indentation = ' ';\r\n\r\n let newCaretPosition;\r\n\r\n /**\r\n * For Tab pressing, just add an indentation to the caret position\r\n */\r\n if (!isShiftPressed) {\r\n newCaretPosition = caretPosition + indentation.length;\r\n\r\n textarea.value = value.substring(0, caretPosition) + indentation + value.substring(caretPosition);\r\n } else {\r\n /**\r\n * For Shift+Tab pressing, remove an indentation from the start of line\r\n */\r\n const currentLineStart = getLineStartPosition(value, caretPosition);\r\n const firstLineChars = value.substr(currentLineStart, indentation.length);\r\n\r\n if (firstLineChars !== indentation) {\r\n return;\r\n }\r\n\r\n /**\r\n * Trim the first two chars from the start of line\r\n */\r\n textarea.value = value.substring(0, currentLineStart) + value.substring(currentLineStart + indentation.length);\r\n newCaretPosition = caretPosition - indentation.length;\r\n }\r\n\r\n /**\r\n * Restore the caret\r\n */\r\n textarea.setSelectionRange(newCaretPosition, newCaretPosition);\r\n }\r\n\r\n /**\r\n * Create Tool's view\r\n * @returns\r\n */\r\n private drawView(): HTMLDivElement {\r\n const wrapper = document.createElement('div');\r\n const wrapperHolder = document.createElement('div');\r\n const wrapperSelectorHolder = document.createElement('div');\r\n const wrapperLang = document.createElement('div');\r\n const wrapperCopy = document.createElement('div');\r\n const wrapperCopyTip = document.createElement('div');\r\n \r\n\r\n const selectorLanguage = document.createElement('select');\r\n const selectorTheme = document.createElement('select');\r\n const span = document.createElement('span');\r\n const textarea = document.createElement('textarea');\r\n\r\n wrapper.classList.add(this.CSS.baseClass, this.CSS.wrapper);\r\n wrapperHolder.classList.add('ce-editorjs-x-shiki__code');\r\n wrapperSelectorHolder.classList.add('ce-editorjs-x-shiki__selector');\r\n wrapperLang.classList.add('ce-editorjs-x-shiki__lang');\r\n wrapperCopy.classList.add('ce-editorjs-x-shiki__copy');\r\n wrapperCopyTip.classList.add('ce-editorjs-x-shiki__copy_tip');\r\n\r\n selectorLanguage.classList.add(this.CSS.selectorLanguage);\r\n //selectorTheme.classList.add(this.CSS.selectorTheme);\r\n textarea.classList.add(this.CSS.textarea, this.CSS.input);\r\n\r\n wrapperLang.innerHTML = this.data.lang\r\n wrapperCopy.innerHTML = IconCopy;\r\n wrapperCopyTip.innerText=this.api.i18n.t('Copied');\r\n\r\n \r\n\r\n languages.forEach((lang) => {\r\n const option = document.createElement('option');\r\n option.value = lang.id;\r\n option.text = lang.name;\r\n selectorLanguage.appendChild(option);\r\n });\r\n selectorLanguage.value = this.data.lang\r\n\r\n // themes.forEach((theme) => {\r\n // const option = document.createElement('option');\r\n // option.value = theme.id;\r\n // option.text = theme.displayName;\r\n // selectorTheme.appendChild(option);\r\n // });\r\n // selectorTheme.value = this.data.theme\r\n\r\n textarea.value = this.data.code;\r\n textarea.placeholder = this.placeholder;\r\n textarea.spellcheck = false;\r\n textarea.autocomplete = \"off\"\r\n textarea.autocapitalize = \"off\"\r\n\r\n if (this.readOnly) {\r\n textarea.disabled = true;\r\n }\r\n\r\n wrapperHolder.appendChild(span);\r\n wrapperHolder.appendChild(textarea);\r\n \r\n if(!this.readOnly) {\r\n wrapperSelectorHolder.appendChild(selectorLanguage);\r\n //wrapperSelectorHolder.appendChild(selectorTheme);\r\n \r\n } else {\r\n wrapperSelectorHolder.appendChild(wrapperLang);\r\n \r\n }\r\n wrapperCopy.appendChild(wrapperCopyTip);\r\n\r\n wrapperSelectorHolder.appendChild(wrapperCopy);\r\n wrapper.appendChild(wrapperSelectorHolder);\r\n \r\n wrapper.appendChild(wrapperHolder);\r\n //wrapper.appendChild(wrapperLang);\r\n\r\n this.runShiki().then(({ html, preStyle }) => {\r\n\r\n span.innerHTML = html\r\n wrapper?.setAttribute('style', preStyle)\r\n selectorLanguage.setAttribute('style', preStyle)\r\n selectorTheme.setAttribute('style', preStyle)\r\n })\r\n\r\n selectorLanguage.addEventListener('change', (event: Event) => {\r\n const lang = (event.target as HTMLSelectElement).value\r\n this._selectorLanguage = lang\r\n this.runShiki().then(({ html, preStyle }) => {\r\n span.innerHTML = html\r\n wrapperLang.innerHTML = lang\r\n })\r\n })\r\n\r\n selectorTheme.addEventListener('change', (event: Event) => {\r\n const theme = (event.target as HTMLSelectElement).value\r\n this._selectorTheme = theme\r\n this.runShiki().then(({ html, preStyle }) => {\r\n span.innerHTML = html\r\n wrapper?.setAttribute('style', preStyle)\r\n selectorLanguage.setAttribute('style', preStyle)\r\n selectorTheme.setAttribute('style', preStyle)\r\n })\r\n })\r\n\r\n textarea.addEventListener('input', () => {\r\n this.data.code = textarea.value\r\n this.runShiki().then(({ html, preStyle }) => {\r\n span.innerHTML = html\r\n wrapper?.setAttribute('style', preStyle)\r\n selectorLanguage.setAttribute('style', preStyle)\r\n selectorTheme.setAttribute('style', preStyle)\r\n })\r\n })\r\n\r\n /**\r\n * Enable keydown handlers\r\n */\r\n textarea.addEventListener('keydown', (event) => {\r\n switch (event.code) {\r\n case 'Tab':\r\n this.tabHandler(event);\r\n this.data.code = textarea.value\r\n this.runShiki().then(({ html, preStyle }) => {\r\n span.innerHTML = html\r\n })\r\n break;\r\n }\r\n });\r\n wrapperCopy.addEventListener('click', (event: MouseEvent) => {\r\n this.copyCode(this.data.code,event);\r\n });\r\n\r\n this.nodes.textarea = textarea;\r\n\r\n return wrapper;\r\n }\r\n\r\n private async runShiki(): Promise<{ html: string, preStyle: string }> {\r\n let preStyle = ''\r\n\r\n const html = await codeToHtml(this.data.code, {\r\n lang: this._selectorLanguage,\r\n theme: this._selectorTheme,\r\n transformers: [\r\n {\r\n preprocess(code) {\r\n // if (code.endsWith('\\n'))\r\n return `${code}\\n`\r\n },\r\n pre(node) {\r\n this.addClassToHast(node, 'ce-editorjs-x-shiki__span')\r\n preStyle = node.properties?.style as string || ''\r\n },\r\n }\r\n ]\r\n })\r\n\r\n return {\r\n html,\r\n preStyle\r\n }\r\n\r\n }\r\n\r\n private copyCode(code: string, event: MouseEvent) {\r\n if (this.data.code) {\r\n navigator.clipboard.writeText(code)\r\n .then(() => { \r\n if (event.target) {\r\n const parentEle = (event.target as HTMLElement).parentElement;\r\n if (parentEle) {\r\n const tooltip = parentEle.lastChild as HTMLElement; \r\n if (tooltip) {\r\n tooltip.classList.add('visible');\r\n setTimeout(() => {\r\n tooltip.classList.remove('visible');\r\n\r\n }, 2000);\r\n }\r\n }\r\n }\r\n\r\n \r\n })\r\n .catch((err) => {\r\n console.error(err);\r\n alert(\"Unable to copy\");\r\n });\r\n }\r\n }\r\n}\r\n","/**\r\n * Return the position of line starting from passed point\r\n *\r\n * ┌───────────────┐\r\n * │1234\\n │\r\n * │2eda | dadd\\n │ <-- returns 5\r\n * └───────────────┘\r\n * @param string - string to process\r\n * @param position - search starting position\r\n * @returns\r\n */\r\nexport function getLineStartPosition(string: string, position: number): number {\r\n const charLength = 1;\r\n let char = '';\r\n\r\n /**\r\n * Iterate through all the chars before the position till the\r\n * - end of line (\\n)\r\n * - or start of string (position === 0)\r\n */\r\n while (char !== '\\n' && position > 0) {\r\n position = position - charLength;\r\n char = string.substr(position, charLength);\r\n }\r\n\r\n /**\r\n * Do not count the linebreak symbol because it is related to the previous line\r\n */\r\n if (char === '\\n') {\r\n position += 1;\r\n }\r\n\r\n return position;\r\n}\r\n","import \"./index.css\";\r\n\r\n\r\nimport { make } from \"@editorjs/dom\";\r\nimport type { API, BlockAPI, BlockTool } from \"@ebl-vue/editorjs\";\r\nimport { IconQuote } from \"../../icons\";\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Data structure for the Quote block.\r\n */\r\nexport interface QuoteData {\r\n text: string;\r\n}\r\n\r\n/**\r\n * Parameters for the Quote constructor.\r\n */\r\ninterface QuoteParams {\r\n data: QuoteData;\r\n api: API;\r\n readOnly: boolean;\r\n block: BlockAPI;\r\n}\r\n\r\n/**\r\n * CSS class names used in the Quote block.\r\n */\r\ninterface QuoteCSS {\r\n baseClass: string;\r\n wrapper: string;\r\n input: string;\r\n text: string;\r\n}\r\n\r\n\r\n\r\n/**\r\n * Quote class representing a customizable quote block for Editor.js.\r\n */\r\nexport default class Quote implements BlockTool {\r\n api: API;\r\n readOnly: boolean;\r\n\r\n\r\n private _data: QuoteData;\r\n private _CSS: QuoteCSS;\r\n private _quoteElement!: HTMLElement;\r\n\r\n /**\r\n * Creates an instance of the Quote block.\r\n * @param params - The parameters for the Quote block.\r\n */\r\n constructor({ data, api, readOnly }: QuoteParams) {\r\n\r\n\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n this._data = {\r\n text: data.text || \"\"\r\n };\r\n\r\n this._CSS = {\r\n baseClass: this.api.styles.block,\r\n wrapper: \"cdx-quote\",\r\n text: \"cdx-quote__text\",\r\n input: this.api.styles.input,\r\n };\r\n\r\n }\r\n\r\n static get isReadOnlySupported(): boolean {\r\n return true;\r\n }\r\n\r\n static get toolbox() {\r\n return {\r\n icon: IconQuote,\r\n title: \"Quote\",\r\n };\r\n }\r\n\r\n static get contentless(): boolean {\r\n return true;\r\n }\r\n\r\n static get enableLineBreaks(): boolean {\r\n return true;\r\n }\r\n\r\n\r\n\r\n static get conversionConfig() {\r\n return {\r\n import: \"text\",\r\n\r\n export: function (quoteData: QuoteData): string {\r\n return quoteData.text;\r\n },\r\n };\r\n }\r\n\r\n\r\n get CSS(): QuoteCSS {\r\n return {\r\n baseClass: this.api.styles.block,\r\n wrapper: \"cdx-quote\",\r\n text: \"cdx-quote__text\",\r\n input: this.api.styles.input,\r\n };\r\n }\r\n\r\n\r\n\r\n render(): HTMLElement {\r\n const container = make(\"div\", [this._CSS.baseClass, this._CSS.wrapper]);\r\n this._quoteElement = make(\r\n \"blockquote\",\r\n [this._CSS.input, this._CSS.text, \"cdx-block-quote\"],\r\n {\r\n contentEditable: !this.readOnly,\r\n innerHTML: this._data.text,\r\n }\r\n );\r\n\r\n this._quoteElement.addEventListener(\"keydown\", (event: KeyboardEvent) =>\r\n this.handleKeydown(event)\r\n );\r\n\r\n container.appendChild(this._quoteElement);\r\n return container;\r\n }\r\n\r\n\r\n get currentItem(): HTMLElement {\r\n let currentNode = window.getSelection()!.anchorNode;\r\n\r\n if (currentNode!.nodeType !== Node.ELEMENT_NODE) {\r\n currentNode = currentNode!.parentNode;\r\n }\r\n\r\n return (currentNode as Element).closest(`.${this.CSS.text}`) as HTMLElement;\r\n }\r\n\r\n\r\n handleKeydown(event: KeyboardEvent) {\r\n const currentItem = this._quoteElement;\r\n\r\n if (event.key === \"Enter\") {\r\n if (!event.shiftKey) {\r\n event.preventDefault();\r\n this.getOutOfQuote();\r\n }\r\n }\r\n\r\n if (\r\n event.key === \"Backspace\" &&\r\n currentItem.textContent?.trim().length === 0\r\n ) {\r\n event.preventDefault();\r\n\r\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\r\n this.api.blocks.delete(currentBlockIndex);\r\n this.api.blocks.insert(\"paragraph\", { text: \"\" });\r\n this.api.caret.setToBlock(currentBlockIndex);\r\n\r\n return;\r\n }\r\n }\r\n\r\n\r\n getOutOfQuote() {\r\n this.api.blocks.insert();\r\n this.api.caret.setToBlock(this.api.blocks.getCurrentBlockIndex());\r\n }\r\n\r\n\r\n\r\n\r\n save(quoteElement: HTMLDivElement): QuoteData {\r\n const text = quoteElement.querySelector(`.${this._CSS.text}`);\r\n\r\n return Object.assign(this._data, {\r\n text: text?.innerHTML ?? \"\",\r\n });\r\n }\r\n\r\n static get sanitize() {\r\n return {\r\n text: {\r\n br: true,\r\n },\r\n };\r\n }\r\n\r\n\r\n\r\n\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\nimport {API, BlockTool, BlockToolConstructorOptions, BlockToolData, ToolboxConfig, PasteConfig, PasteEvent} from \"@ebl-vue/editorjs\";\r\n\r\nimport {IconDelimiter} from '../../icons';\r\n\r\n\r\n\r\n\r\nexport default class Delimiter implements BlockTool {\r\n\r\n static get isReadOnlySupported(): boolean {\r\n return true;\r\n }\r\n\r\n\r\n static get contentless(): boolean {\r\n return true;\r\n }\r\n\r\n private api: API\r\n\r\n private _CSS: {\r\n block: string\r\n wrapper: string\r\n }\r\n\r\n\r\n\r\n private _element: HTMLDivElement\r\n private data: any;\r\n\r\n\r\n constructor({data, config, api}: BlockToolConstructorOptions) {\r\n this.api = api;\r\n\r\n this._CSS = {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-delimiter'\r\n };\r\n\r\n this._element = this.drawView();\r\n this.data = data;\r\n\r\n }\r\n\r\n /**\r\n * Create Tool's view\r\n * @return {HTMLDivElement}\r\n * @private\r\n */\r\n drawView(): HTMLDivElement {\r\n let wrapper = document.createElement('div');\r\n let lineWrapper = document.createElement('div');\r\n let lineDiv = document.createElement('div');\r\n \r\n wrapper.classList.add(this._CSS.wrapper, this._CSS.block);\r\n lineWrapper.classList.add('ce-delimiter__line__wrapper');\r\n lineDiv.classList.add('ce-delimiter__line');\r\n\r\n lineWrapper.appendChild(lineDiv);\r\n wrapper.appendChild(lineWrapper);\r\n\r\n return wrapper;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n * @returns {HTMLDivElement}\r\n * @public\r\n */\r\n render(): HTMLDivElement {\r\n console.log(this.data);\r\n return this._element;\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n * @param {HTMLDivElement} toolsContent - Paragraph tools rendered view\r\n * @returns {DelimiterData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLElement): BlockToolData {\r\n return {};\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @return {{icon: string, title: string}}\r\n */\r\n static get toolbox(): ToolboxConfig {\r\n return {\r\n icon: IconDelimiter,\r\n title: 'Delimiter'\r\n };\r\n }\r\n\r\n /**\r\n * Delimiter onPaste configuration\r\n *\r\n * @public\r\n */\r\n static get pasteConfig(): PasteConfig {\r\n return { tags: ['HR'] };\r\n }\r\n\r\n /**\r\n * On paste callback that is fired from Editor\r\n *\r\n * @param {PasteEvent} event - event with pasted data\r\n */\r\n onPaste(event: PasteEvent): void {\r\n this.data = {};\r\n }\r\n}\r\n\r\n","/**\r\n * Default css prefix for list\r\n */\r\nexport const CssPrefix = 'cdx-list';\r\n","import { CssPrefix } from '../styles/CssPrefix';\r\n/**\r\n * CSS classes for the List Tool\r\n */\r\nexport const DefaultListCssClasses = {\r\n wrapper: CssPrefix,\r\n item: `${CssPrefix}__item`,\r\n itemContent: `${CssPrefix}__item-content`,\r\n itemChildren: `${CssPrefix}__item-children`,\r\n};\r\n\r\n/**\r\n * Interface that represents default list css classes\r\n */\r\nexport interface ListCssClasses {\r\n /**\r\n * CSS class of the whole list wrapper\r\n */\r\n wrapper: string;\r\n\r\n /**\r\n * CSS class of the list item\r\n */\r\n item: string;\r\n\r\n /**\r\n * CSS class of the list item content element\r\n */\r\n itemContent: string;\r\n\r\n /**\r\n * CSS class of the children item wrapper\r\n */\r\n itemChildren: string;\r\n}\r\n\r\n/**\r\n * Interface that represents all list renderer classes\r\n */\r\nexport interface ListRendererInterface<ItemMeta> {\r\n /**\r\n * Renders wrapper for list\r\n * @param isRoot - boolean variable that represents level of the wrappre (root or childList)\r\n * @returns - created html ul element\r\n */\r\n renderWrapper: (isRoot: boolean) => HTMLElement;\r\n\r\n /**\r\n * Redners list item element\r\n * @param content - content of the list item\r\n * @returns - created html list item element\r\n */\r\n renderItem: (content: string, meta: ItemMeta) => HTMLElement;\r\n\r\n /**\r\n * Return the item content\r\n * @param {Element} item - item wrapper (<li>)\r\n * @returns {string}\r\n */\r\n getItemContent: (item: Element) => string;\r\n\r\n /**\r\n * Return meta object of certain element\r\n * @param {Element} item - item of the list to get meta from\r\n * @returns {ItemMeta} Item meta object\r\n */\r\n getItemMeta: (item: Element) => ItemMeta;\r\n\r\n /**\r\n * Returns default item meta used on creation of the new item\r\n */\r\n composeDefaultMeta: () => ItemMeta;\r\n};\r\n","import type { OrderedListItemMeta } from '../types/ItemMeta';\r\nimport type { ListConfig } from '../types/ListParams';\r\nimport { isEmpty, make } from '@editorjs/dom';\r\nimport { DefaultListCssClasses } from './ListRenderer';\r\nimport type { ListCssClasses, ListRendererInterface } from './ListRenderer';\r\nimport { CssPrefix } from '../styles/CssPrefix';\r\n\r\n/**\r\n * Interface that represents all list used only in unordered list rendering\r\n */\r\ninterface OrderedListCssClasses extends ListCssClasses {\r\n /**\r\n * CSS class of the ordered list\r\n */\r\n orderedList: string;\r\n}\r\n\r\n/**\r\n * Class that is responsible for ordered list rendering\r\n */\r\nexport class OrderedListRenderer implements ListRendererInterface<OrderedListItemMeta> {\r\n /**\r\n * Tool's configuration\r\n */\r\n protected config?: ListConfig;\r\n\r\n /**\r\n * Is Editorjs List Tool read-only option\r\n */\r\n private readOnly: boolean;\r\n\r\n /**\r\n * Getter for all CSS classes used in unordered list rendering\r\n */\r\n private static get CSS(): OrderedListCssClasses {\r\n return {\r\n ...DefaultListCssClasses,\r\n orderedList: `${CssPrefix}-ordered`,\r\n };\r\n }\r\n\r\n /**\r\n * Assign passed readonly mode and config to relevant class properties\r\n * @param readonly - read-only mode flag\r\n * @param config - user config for Tool\r\n */\r\n constructor(readonly: boolean, config?: ListConfig) {\r\n this.config = config;\r\n this.readOnly = readonly;\r\n }\r\n\r\n /**\r\n * Renders ol wrapper for list\r\n * @param isRoot - boolean variable that represents level of the wrappre (root or childList)\r\n * @returns - created html ol element\r\n */\r\n public renderWrapper(isRoot: boolean): HTMLOListElement {\r\n let wrapperElement: HTMLOListElement;\r\n\r\n /**\r\n * Check if it's root level\r\n */\r\n if (isRoot === true) {\r\n wrapperElement = make('ol', [OrderedListRenderer.CSS.wrapper, OrderedListRenderer.CSS.orderedList]) as HTMLOListElement;\r\n } else {\r\n wrapperElement = make('ol', [OrderedListRenderer.CSS.orderedList, OrderedListRenderer.CSS.itemChildren]) as HTMLOListElement;\r\n }\r\n\r\n return wrapperElement;\r\n }\r\n\r\n /**\r\n * Redners list item element\r\n * @param content - content used in list item rendering\r\n * @param _meta - meta of the list item unused in rendering of the ordered list\r\n * @returns - created html list item element\r\n */\r\n public renderItem(content: string, _meta: OrderedListItemMeta): HTMLLIElement {\r\n const itemWrapper = make('li', OrderedListRenderer.CSS.item);\r\n const itemContent = make('div', OrderedListRenderer.CSS.itemContent, {\r\n innerHTML: content,\r\n contentEditable: (!this.readOnly).toString(),\r\n });\r\n\r\n itemWrapper.appendChild(itemContent);\r\n\r\n return itemWrapper as HTMLLIElement;\r\n }\r\n\r\n /**\r\n * Return the item content\r\n * @param item - item wrapper (<li>)\r\n * @returns - item content string\r\n */\r\n public getItemContent(item: Element): string {\r\n const contentNode = item.querySelector(`.${OrderedListRenderer.CSS.itemContent}`);\r\n\r\n if (!contentNode) {\r\n return '';\r\n }\r\n\r\n if (isEmpty(contentNode)) {\r\n return '';\r\n }\r\n\r\n return contentNode.innerHTML;\r\n }\r\n\r\n /**\r\n * Returns item meta, for ordered list\r\n * @returns item meta object\r\n */\r\n public getItemMeta(): OrderedListItemMeta {\r\n return {};\r\n }\r\n\r\n /**\r\n * Returns default item meta used on creation of the new item\r\n */\r\n public composeDefaultMeta(): OrderedListItemMeta {\r\n return {};\r\n }\r\n}\r\n","import type { UnorderedListItemMeta } from '../types/ItemMeta';\r\nimport type { ListConfig } from '../types/ListParams';\r\nimport { make, isEmpty } from '@editorjs/dom';\r\nimport { DefaultListCssClasses } from './ListRenderer';\r\nimport type { ListCssClasses, ListRendererInterface } from './ListRenderer';\r\nimport { CssPrefix } from '../styles/CssPrefix';\r\n\r\n/**\r\n * Interface that represents all list used only in unordered list rendering\r\n */\r\ninterface UnoderedListCssClasses extends ListCssClasses {\r\n /**\r\n * CSS class of the unordered list\r\n */\r\n unorderedList: string;\r\n}\r\n\r\n/**\r\n * Class that is responsible for unordered list rendering\r\n */\r\nexport class UnorderedListRenderer implements ListRendererInterface<UnorderedListItemMeta> {\r\n /**\r\n * Tool's configuration\r\n */\r\n protected config?: ListConfig;\r\n\r\n /**\r\n * Is Editorjs List Tool read-only option\r\n */\r\n private readOnly: boolean;\r\n\r\n /**\r\n * Getter for all CSS classes used in unordered list rendering\r\n */\r\n private static get CSS(): UnoderedListCssClasses {\r\n return {\r\n ...DefaultListCssClasses,\r\n unorderedList: `${CssPrefix}-unordered`,\r\n };\r\n }\r\n\r\n /**\r\n * Assign passed readonly mode and config to relevant class properties\r\n * @param readonly - read-only mode flag\r\n * @param config - user config for Tool\r\n */\r\n constructor(readonly: boolean, config?: ListConfig) {\r\n this.config = config;\r\n this.readOnly = readonly;\r\n }\r\n\r\n /**\r\n * Renders ol wrapper for list\r\n * @param isRoot - boolean variable that represents level of the wrappre (root or childList)\r\n * @returns - created html ul element\r\n */\r\n public renderWrapper(isRoot: boolean): HTMLUListElement {\r\n let wrapperElement: HTMLUListElement;\r\n\r\n /**\r\n * Check if it's root level\r\n */\r\n if (isRoot === true) {\r\n wrapperElement = make('ul', [UnorderedListRenderer.CSS.wrapper, UnorderedListRenderer.CSS.unorderedList]) as HTMLUListElement;\r\n } else {\r\n wrapperElement = make('ul', [UnorderedListRenderer.CSS.unorderedList, UnorderedListRenderer.CSS.itemChildren]) as HTMLUListElement;\r\n }\r\n\r\n return wrapperElement;\r\n }\r\n\r\n /**\r\n * Redners list item element\r\n * @param content - content used in list item rendering\r\n * @param _meta - meta of the list item unused in rendering of the unordered list\r\n * @returns - created html list item element\r\n */\r\n public renderItem(content: string, _meta: UnorderedListItemMeta): HTMLLIElement {\r\n const itemWrapper = make('li', UnorderedListRenderer.CSS.item);\r\n const itemContent = make('div', UnorderedListRenderer.CSS.itemContent, {\r\n innerHTML: content,\r\n contentEditable: (!this.readOnly).toString(),\r\n });\r\n\r\n itemWrapper.appendChild(itemContent);\r\n\r\n return itemWrapper as HTMLLIElement;\r\n }\r\n\r\n /**\r\n * Return the item content\r\n * @param item - item wrapper (<li>)\r\n * @returns - item content string\r\n */\r\n public getItemContent(item: Element): string {\r\n const contentNode = item.querySelector(`.${UnorderedListRenderer.CSS.itemContent}`);\r\n\r\n if (!contentNode) {\r\n return '';\r\n }\r\n\r\n if (isEmpty(contentNode)) {\r\n return '';\r\n }\r\n\r\n return contentNode.innerHTML;\r\n }\r\n\r\n /**\r\n * Returns item meta, for unordered list\r\n * @returns Item meta object\r\n */\r\n public getItemMeta(): UnorderedListItemMeta {\r\n return {};\r\n }\r\n\r\n /**\r\n * Returns default item meta used on creation of the new item\r\n */\r\n public composeDefaultMeta(): UnorderedListItemMeta {\r\n return {};\r\n }\r\n}\r\n","/**\r\n * Type guard to check if a node is an HTMLElement, then we can safely use it as an HTMLElement\r\n * @param node - Node to be checked, wherever it is an HTMLElement\r\n */\r\nexport function isHtmlElement(node: Node): node is HTMLElement {\r\n // node is an HTMLElement if it is an element node\r\n return node.nodeType === Node.ELEMENT_NODE;\r\n}\r\n","import type { ChecklistItemMeta } from '../types/ItemMeta';\r\nimport type { ListConfig } from '../types/ListParams';\r\nimport { isEmpty, make } from '@editorjs/dom';\r\nimport { DefaultListCssClasses } from './ListRenderer';\r\nimport type { ListCssClasses, ListRendererInterface } from './ListRenderer';\r\nimport { CssPrefix } from '../styles/CssPrefix';\r\nimport { IconCheck } from \"../../../icons\"; \r\n\r\n/**\r\n * Interface that represents all list used only in unordered list rendering\r\n */\r\ninterface ChecklistCssClasses extends ListCssClasses {\r\n /**\r\n * CSS class of the checklist\r\n */\r\n checklist: string;\r\n\r\n /**\r\n * CSS class of the checked checkbox\r\n */\r\n itemChecked: string;\r\n\r\n /**\r\n * CSS class for the special hover behavior of the checkboc\r\n */\r\n noHover: string;\r\n\r\n /**\r\n * CSS class of the checkbox\r\n */\r\n checkbox: string;\r\n\r\n /**\r\n * CSS class of the checkbox container\r\n */\r\n checkboxContainer: string;\r\n\r\n /**\r\n * CSS class for disabled checkbox check\r\n */\r\n checkboxCheckDisabled: string;\r\n}\r\n\r\n/**\r\n * Class that is responsible for checklist rendering\r\n */\r\nexport class CheckListRenderer implements ListRendererInterface<ChecklistItemMeta> {\r\n /**\r\n * Tool's configuration\r\n */\r\n protected config?: ListConfig;\r\n\r\n /**\r\n * Is Editorjs List Tool read-only option\r\n */\r\n private readOnly: boolean;\r\n\r\n /**\r\n * Getter for all CSS classes used in unordered list rendering\r\n */\r\n private static get CSS(): ChecklistCssClasses {\r\n return {\r\n ...DefaultListCssClasses,\r\n checklist: `${CssPrefix}-checklist`,\r\n itemChecked: `${CssPrefix}__checkbox--checked`,\r\n noHover: `${CssPrefix}__checkbox--no-hover`,\r\n checkbox: `${CssPrefix}__checkbox-check`,\r\n checkboxContainer: `${CssPrefix}__checkbox`,\r\n checkboxCheckDisabled: `${CssPrefix}__checkbox-check--disabled`,\r\n };\r\n }\r\n\r\n /**\r\n * Assign passed readonly mode and config to relevant class properties\r\n * @param readonly - read-only mode flag\r\n * @param config - user config for Tool\r\n */\r\n constructor(readonly: boolean, config?: ListConfig) {\r\n this.config = config;\r\n this.readOnly = readonly;\r\n }\r\n\r\n /**\r\n * Renders ul wrapper for list\r\n * @param isRoot - boolean variable that represents level of the wrappre (root or childList)\r\n * @returns - created html ul element\r\n */\r\n public renderWrapper(isRoot: boolean): HTMLUListElement {\r\n let wrapperElement: HTMLUListElement;\r\n\r\n /**\r\n * Check if it's root level\r\n */\r\n if (isRoot === true) {\r\n wrapperElement = make('ul', [CheckListRenderer.CSS.wrapper, CheckListRenderer.CSS.checklist]) as HTMLUListElement;\r\n\r\n /**\r\n * Delegate clicks from wrapper to items\r\n */\r\n wrapperElement.addEventListener('click', (event) => {\r\n const target = event.target as Element | null;\r\n\r\n if (target) {\r\n const checkbox = target.closest(`.${CheckListRenderer.CSS.checkboxContainer}`);\r\n\r\n if (checkbox && checkbox.contains(target)) {\r\n this.toggleCheckbox(checkbox);\r\n }\r\n }\r\n });\r\n } else {\r\n wrapperElement = make('ul', [CheckListRenderer.CSS.checklist, CheckListRenderer.CSS.itemChildren]) as HTMLUListElement;\r\n }\r\n\r\n return wrapperElement;\r\n }\r\n\r\n /**\r\n * Redners list item element\r\n * @param content - content used in list item rendering\r\n * @param meta - meta of the list item used in rendering of the checklist\r\n * @returns - created html list item element\r\n */\r\n public renderItem(content: string, meta: ChecklistItemMeta): HTMLLIElement {\r\n const itemWrapper = make('li', [CheckListRenderer.CSS.item, CheckListRenderer.CSS.item]);\r\n const itemContent = make('div', CheckListRenderer.CSS.itemContent, {\r\n innerHTML: content,\r\n contentEditable: (!this.readOnly).toString(),\r\n });\r\n\r\n const checkbox = make('span', CheckListRenderer.CSS.checkbox);\r\n const checkboxContainer = make('div', CheckListRenderer.CSS.checkboxContainer);\r\n\r\n if (meta.checked === true) {\r\n checkboxContainer.classList.add(CheckListRenderer.CSS.itemChecked);\r\n }\r\n\r\n // Disable checkbox interaction in read-only mode\r\n if (this.readOnly) {\r\n checkboxContainer.classList.add(CheckListRenderer.CSS.checkboxCheckDisabled);\r\n }\r\n\r\n checkbox.innerHTML = IconCheck;\r\n checkboxContainer.appendChild(checkbox);\r\n\r\n itemWrapper.appendChild(checkboxContainer);\r\n itemWrapper.appendChild(itemContent);\r\n\r\n return itemWrapper as HTMLLIElement;\r\n }\r\n\r\n /**\r\n * Return the item content\r\n * @param item - item wrapper (<li>)\r\n * @returns - item content string\r\n */\r\n public getItemContent(item: Element): string {\r\n const contentNode = item.querySelector(`.${CheckListRenderer.CSS.itemContent}`);\r\n\r\n if (!contentNode) {\r\n return '';\r\n }\r\n\r\n if (isEmpty(contentNode)) {\r\n return '';\r\n }\r\n\r\n return contentNode.innerHTML;\r\n }\r\n\r\n /**\r\n * Return meta object of certain element\r\n * @param item - will be returned meta information of this item\r\n * @returns Item meta object\r\n */\r\n public getItemMeta(item: Element): ChecklistItemMeta {\r\n const checkbox = item.querySelector(`.${CheckListRenderer.CSS.checkboxContainer}`);\r\n\r\n return {\r\n checked: checkbox ? checkbox.classList.contains(CheckListRenderer.CSS.itemChecked) : false,\r\n };\r\n }\r\n\r\n /**\r\n * Returns default item meta used on creation of the new item\r\n */\r\n public composeDefaultMeta(): ChecklistItemMeta {\r\n return { checked: false };\r\n }\r\n\r\n /**\r\n * Toggle checklist item state\r\n * @param checkbox - checkbox element to be toggled\r\n */\r\n private toggleCheckbox(checkbox: Element): void {\r\n checkbox.classList.toggle(CheckListRenderer.CSS.itemChecked);\r\n checkbox.classList.add(CheckListRenderer.CSS.noHover);\r\n checkbox.addEventListener('mouseleave', () => this.removeSpecialHoverBehavior(checkbox), { once: true });\r\n }\r\n\r\n /**\r\n * Removes class responsible for special hover behavior on an item\r\n * @param el - item wrapper\r\n */\r\n private removeSpecialHoverBehavior(el: Element): void {\r\n el.classList.remove(CheckListRenderer.CSS.noHover);\r\n }\r\n}\r\n","/**\r\n * Get all siblings before passed element, or after it\r\n * @param element - html element whose siblings would be returned\r\n * @param direction - wherever siblings would be returned, after element of before it\r\n */\r\nexport function getSiblings(element: HTMLElement, direction: 'after' | 'before' = 'after'): Element[] | null {\r\n const siblings: Element[] = [];\r\n\r\n let nextElementSibling: HTMLElement;\r\n\r\n /**\r\n * Method that is responsible for getting next element sibling responsible to the direction variable\r\n * @param el - current element\r\n * @returns HTML element of the sibling\r\n */\r\n function getNextElementSibling(el: HTMLElement): HTMLElement {\r\n /**\r\n * Get first sibling element respectfully to passed direction\r\n */\r\n switch (direction) {\r\n case 'after':\r\n return el.nextElementSibling as HTMLElement;\r\n\r\n case 'before':\r\n return el.previousElementSibling as HTMLElement;\r\n }\r\n }\r\n\r\n nextElementSibling = getNextElementSibling(element);\r\n\r\n /**\r\n * Iterate by all siblings elements\r\n */\r\n while (nextElementSibling !== null) {\r\n siblings.push(nextElementSibling);\r\n\r\n /**\r\n * Get next element sibling\r\n */\r\n nextElementSibling = getNextElementSibling(nextElementSibling);\r\n }\r\n\r\n /**\r\n * Check that formed siblings array is not empty\r\n * If it is emtpy, return null\r\n */\r\n if (siblings.length !== 0) {\r\n return siblings;\r\n }\r\n\r\n return null;\r\n}\r\n","import { DefaultListCssClasses } from '../ListRenderer';\r\nimport type { ItemChildWrapperElement, ItemElement } from '../types/Elements';\r\n\r\n/**\r\n * Get child items of the passed element\r\n * @param element - child items would be got from this element\r\n * @param firstLevelChildren - if method should return all level child items or only first level ones\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-duplicate-type-constituents\r\nexport function getChildItems(element: ItemElement | ItemChildWrapperElement, firstLevelChildren: boolean = true): ItemElement[] {\r\n let itemChildWrapper: HTMLElement = element;\r\n\r\n /**\r\n * If passed element is list item than get item's child wrapper\r\n */\r\n if (element.classList.contains(DefaultListCssClasses.item)) {\r\n itemChildWrapper = element.querySelector(`.${DefaultListCssClasses.itemChildren}`) as HTMLElement;\r\n }\r\n\r\n /**\r\n * Check if itemChildWrapper is not null\r\n */\r\n if (itemChildWrapper === null) {\r\n return [];\r\n }\r\n\r\n if (firstLevelChildren) {\r\n /**\r\n * Filter first level child items of the curret child item wrapper\r\n * In case that child could be not only list item\r\n */\r\n return Array.from(itemChildWrapper.querySelectorAll(`:scope > .${DefaultListCssClasses.item}`));\r\n } else {\r\n /**\r\n * Filter all levels child items of the current child item wrapper\r\n * In case that child could be not only list item\r\n */\r\n return Array.from(itemChildWrapper.querySelectorAll(`.${DefaultListCssClasses.item}`));\r\n }\r\n}\r\n","import type { ItemChildWrapperElement, ItemElement } from '../types/Elements';\r\nimport { DefaultListCssClasses } from '../ListRenderer';\r\n\r\n/**\r\n * Returns child wrapper element of the passed item\r\n * @param item - wrapper element would be got from this item\r\n */\r\nexport function getItemChildWrapper(item: ItemElement): ItemChildWrapperElement | null {\r\n return item.querySelector(`.${DefaultListCssClasses.itemChildren}`);\r\n}\r\n","import { DefaultListCssClasses } from '../ListRenderer';\r\nimport type { ItemChildWrapperElement, ItemElement } from '../types/Elements';\r\nimport { getChildItems } from './getChildItems';\r\nimport { getItemChildWrapper } from './getItemChildWrapper';\r\n\r\n/**\r\n * Method that will remove passed child wrapper if it has no child items\r\n * @param element - child wrapper or actual item, from where we get child wrapper\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-duplicate-type-constituents\r\nexport function removeChildWrapperIfEmpty(element: ItemChildWrapperElement | ItemElement): void {\r\n let itemChildWrapper: HTMLElement | null = element;\r\n\r\n /**\r\n * If passed element is list item than get item's child wrapper\r\n */\r\n if (element.classList.contains(DefaultListCssClasses.item)) {\r\n itemChildWrapper = getItemChildWrapper(element);\r\n }\r\n\r\n if (itemChildWrapper === null) {\r\n return;\r\n }\r\n\r\n /**\r\n * Check that there is at least one item\r\n */\r\n if (getChildItems(itemChildWrapper).length === 0) {\r\n itemChildWrapper.remove();\r\n }\r\n}\r\n","import type { ItemContentElement, ItemElement } from '../types/Elements';\r\nimport { DefaultListCssClasses } from '../ListRenderer';\r\n\r\n/**\r\n * Returns content element of the passed item\r\n * @param item - content element would be got from this item\r\n */\r\nexport function getItemContentElement(item: ItemElement): ItemContentElement | null {\r\n return item.querySelector(`.${DefaultListCssClasses.itemContent}`);\r\n}\r\n","import { focus } from '@editorjs/caret';\r\nimport type { ItemElement } from '../types/Elements';\r\nimport { getItemContentElement } from './getItemContentElement';\r\n\r\n/**\r\n * Sets focus to the item's content\r\n * @param item - item (<li>) to select\r\n * @param atStart - where to set focus: at the start or at the end\r\n */\r\nexport function focusItem(item: ItemElement, atStart: boolean = true): void {\r\n const itemContent = getItemContentElement(item);\r\n\r\n if (!itemContent) {\r\n return;\r\n }\r\n\r\n focus(itemContent, atStart);\r\n}\r\n","import { OrderedListRenderer } from '../ListRenderer/OrderedListRenderer';\r\nimport { UnorderedListRenderer } from '../ListRenderer/UnorderedListRenderer';\r\nimport type { ListConfig, ListData, ListDataStyle } from '../types/ListParams';\r\nimport type { ListItem } from '../types/ListParams';\r\nimport type { ItemElement, ItemChildWrapperElement } from '../types/Elements';\r\nimport { isHtmlElement } from '../utils/type-guards';\r\nimport { getContenteditableSlice, getCaretNodeAndOffset, isCaretAtStartOfInput } from '@editorjs/caret';\r\nimport { DefaultListCssClasses } from '../ListRenderer';\r\nimport type { PasteEvent } from '../types';\r\nimport type { API, BlockAPI, PasteConfig } from '@editorjs/editorjs';\r\nimport type { ListParams } from '..';\r\nimport type { ChecklistItemMeta, ItemMeta, OrderedListItemMeta, UnorderedListItemMeta } from '../types/ItemMeta';\r\nimport type { ListRenderer } from '../types/ListRenderer';\r\nimport { getSiblings } from '../utils/getSiblings';\r\nimport { getChildItems } from '../utils/getChildItems';\r\nimport { isLastItem } from '../utils/isLastItem';\r\nimport { itemHasSublist } from '../utils/itemHasSublist';\r\nimport { getItemChildWrapper } from '../utils/getItemChildWrapper';\r\nimport { removeChildWrapperIfEmpty } from '../utils/removeChildWrapperIfEmpty';\r\nimport { getItemContentElement } from '../utils/getItemContentElement';\r\nimport { focusItem } from '../utils/focusItem';\r\nimport type { OlCounterType } from '../types/OlCounterType';\r\n\r\n/**\r\n * Class that is responsible for list tabulation\r\n */\r\nexport default class ListTabulator<Renderer extends ListRenderer> {\r\n /**\r\n * The Editor.js API\r\n */\r\n private api: API;\r\n\r\n /**\r\n * Is Editorjs List Tool read-only option\r\n */\r\n private readOnly: boolean;\r\n\r\n /**\r\n * Tool's configuration\r\n */\r\n private config?: ListConfig;\r\n\r\n /**\r\n * Full content of the list\r\n */\r\n private data: ListData;\r\n\r\n /**\r\n * Editor block api\r\n */\r\n private block: BlockAPI;\r\n\r\n /**\r\n * Rendered list of items\r\n */\r\n private renderer: Renderer;\r\n\r\n /**\r\n * Wrapper of the whole list\r\n */\r\n private listWrapper: ItemChildWrapperElement | undefined;\r\n\r\n /**\r\n * Getter method to get current item\r\n * @returns current list item or null if caret position is not undefined\r\n */\r\n private get currentItem(): ItemElement | null {\r\n const selection = window.getSelection();\r\n\r\n if (!selection) {\r\n return null;\r\n }\r\n\r\n let currentNode = selection.anchorNode;\r\n\r\n if (!currentNode) {\r\n return null;\r\n }\r\n\r\n if (!isHtmlElement(currentNode)) {\r\n currentNode = currentNode.parentNode;\r\n }\r\n if (!currentNode) {\r\n return null;\r\n }\r\n if (!isHtmlElement(currentNode)) {\r\n return null;\r\n }\r\n\r\n return currentNode.closest(`.${DefaultListCssClasses.item}`);\r\n }\r\n\r\n /**\r\n * Method that returns nesting level of the current item, null if there is no selection\r\n */\r\n private get currentItemLevel(): number | null {\r\n const currentItem = this.currentItem;\r\n\r\n if (currentItem === null) {\r\n return null;\r\n }\r\n\r\n let parentNode = currentItem.parentNode;\r\n\r\n let levelCounter = 0;\r\n\r\n while (parentNode !== null && parentNode !== this.listWrapper) {\r\n if (isHtmlElement(parentNode) && parentNode.classList.contains(DefaultListCssClasses.item)) {\r\n levelCounter += 1;\r\n }\r\n\r\n parentNode = parentNode.parentNode;\r\n }\r\n\r\n /**\r\n * Level counter is number of the parent element, so it should be increased by one\r\n */\r\n return levelCounter + 1;\r\n }\r\n\r\n /**\r\n * Assign all passed params and renderer to relevant class properties\r\n * @param params - tool constructor options\r\n * @param params.data - previously saved data\r\n * @param params.config - user config for Tool\r\n * @param params.api - Editor.js API\r\n * @param params.readOnly - read-only mode flag\r\n * @param renderer - renderer instance initialized in tool class\r\n */\r\n constructor({ data, config, api, readOnly, block }: ListParams, renderer: Renderer) {\r\n this.config = config;\r\n this.data = data as ListData;\r\n this.readOnly = readOnly;\r\n this.api = api;\r\n this.block = block;\r\n\r\n this.renderer = renderer;\r\n }\r\n\r\n /**\r\n * Function that is responsible for rendering list with contents\r\n * @returns Filled with content wrapper element of the list\r\n */\r\n public render(): ItemChildWrapperElement {\r\n this.listWrapper = this.renderer.renderWrapper(true);\r\n\r\n // fill with data\r\n if (this.data.items.length) {\r\n this.appendItems(this.data.items, this.listWrapper);\r\n } else {\r\n this.appendItems(\r\n [\r\n {\r\n content: '',\r\n meta: {},\r\n items: [],\r\n },\r\n ],\r\n this.listWrapper\r\n );\r\n }\r\n\r\n if (!this.readOnly) {\r\n // detect keydown on the last item to escape List\r\n this.listWrapper.addEventListener(\r\n 'keydown',\r\n (event) => {\r\n switch (event.key) {\r\n case 'Enter':\r\n if (!event.shiftKey) {\r\n this.enterPressed(event);\r\n }\r\n break;\r\n case 'Backspace':\r\n this.backspace(event);\r\n break;\r\n case 'Tab':\r\n if (event.shiftKey) {\r\n this.shiftTab(event);\r\n } else {\r\n this.addTab(event);\r\n }\r\n break;\r\n }\r\n },\r\n false\r\n );\r\n }\r\n\r\n /**\r\n * Set start property value from initial data\r\n */\r\n if ('start' in this.data.meta && this.data.meta.start !== undefined) {\r\n this.changeStartWith(this.data.meta.start);\r\n }\r\n\r\n /**\r\n * Set counterType value from initial data\r\n */\r\n if ('counterType' in this.data.meta && this.data.meta.counterType !== undefined) {\r\n this.changeCounters(this.data.meta.counterType);\r\n }\r\n\r\n return this.listWrapper;\r\n }\r\n\r\n /**\r\n * Function that is responsible for list content saving\r\n * @param wrapper - optional argument wrapper\r\n * @returns whole list saved data if wrapper not passes, otherwise will return data of the passed wrapper\r\n */\r\n public save(wrapper?: ItemChildWrapperElement): ListData {\r\n const listWrapper = wrapper ?? this.listWrapper;\r\n\r\n /**\r\n * The method for recursive collecting of the child items\r\n * @param parent - where to find items\r\n */\r\n const getItems = (parent: ItemChildWrapperElement): ListItem[] => {\r\n const children = getChildItems(parent);\r\n\r\n return children.map((el) => {\r\n const subItemsWrapper = getItemChildWrapper(el);\r\n const content = this.renderer.getItemContent(el);\r\n const meta = this.renderer.getItemMeta(el);\r\n const subItems = subItemsWrapper ? getItems(subItemsWrapper) : [];\r\n\r\n return {\r\n content,\r\n meta,\r\n items: subItems,\r\n };\r\n });\r\n };\r\n\r\n const composedListItems = listWrapper ? getItems(listWrapper) : [];\r\n\r\n let dataToSave: ListData = {\r\n style: this.data.style,\r\n meta: {} as ItemMeta,\r\n items: composedListItems,\r\n };\r\n\r\n if (this.data.style === 'ordered') {\r\n dataToSave.meta = {\r\n start: (this.data.meta as OrderedListItemMeta).start,\r\n counterType: (this.data.meta as OrderedListItemMeta).counterType,\r\n };\r\n }\r\n\r\n return dataToSave;\r\n }\r\n\r\n /**\r\n * On paste sanitzation config. Allow only tags that are allowed in the Tool.\r\n * @returns - config that determines tags supposted by paste handler\r\n * @todo - refactor and move to list instance\r\n */\r\n public static get pasteConfig(): PasteConfig {\r\n return {\r\n tags: ['OL', 'UL', 'LI'],\r\n };\r\n }\r\n\r\n /**\r\n * Method that specified hot to merge two List blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * Content of the first item of the next List would be merged with deepest item in current list\r\n * Other items of the next List would be appended to the current list without any changes in nesting levels\r\n * @param data - data of the second list to be merged with current\r\n */\r\n public merge(data: ListData): void {\r\n /**\r\n * Get list of all levels children of the previous item\r\n */\r\n const items = this.block.holder.querySelectorAll<ItemElement>(`.${DefaultListCssClasses.item}`);\r\n\r\n const deepestBlockItem = items[items.length - 1];\r\n const deepestBlockItemContentElement = getItemContentElement(deepestBlockItem);\r\n\r\n if (deepestBlockItem === null || deepestBlockItemContentElement === null) {\r\n return;\r\n }\r\n\r\n /**\r\n * Insert trailing html to the deepest block item content\r\n */\r\n deepestBlockItemContentElement.insertAdjacentHTML('beforeend', data.items[0].content);\r\n\r\n if (this.listWrapper === undefined) {\r\n return;\r\n }\r\n\r\n const firstLevelItems = getChildItems(this.listWrapper);\r\n\r\n if (firstLevelItems.length === 0) {\r\n return;\r\n }\r\n\r\n /**\r\n * Get last item of the first level of the list\r\n */\r\n const lastFirstLevelItem = firstLevelItems[firstLevelItems.length - 1];\r\n\r\n /**\r\n * Get child items wrapper of the last item\r\n */\r\n let lastFirstLevelItemChildWrapper = getItemChildWrapper(lastFirstLevelItem);\r\n\r\n /**\r\n * Get first item of the list to be merged with current one\r\n */\r\n const firstItem = data.items.shift();\r\n\r\n /**\r\n * Check that first item exists\r\n */\r\n if (firstItem === undefined) {\r\n return;\r\n }\r\n\r\n /**\r\n * Append child items of the first element\r\n */\r\n if (firstItem.items.length !== 0) {\r\n /**\r\n * Render child wrapper of the last item if it does not exist\r\n */\r\n if (lastFirstLevelItemChildWrapper === null) {\r\n lastFirstLevelItemChildWrapper = this.renderer.renderWrapper(false);\r\n }\r\n\r\n this.appendItems(firstItem.items, lastFirstLevelItemChildWrapper);\r\n }\r\n\r\n if (data.items.length > 0) {\r\n this.appendItems(data.items, this.listWrapper);\r\n }\r\n }\r\n\r\n /**\r\n * On paste callback that is fired from Editor.\r\n * @param event - event with pasted data\r\n * @todo - refactor and move to list instance\r\n */\r\n public onPaste(event: PasteEvent): void {\r\n const list = event.detail.data;\r\n\r\n this.data = this.pasteHandler(list);\r\n\r\n // render new list\r\n const oldView = this.listWrapper;\r\n\r\n if (oldView && oldView.parentNode) {\r\n oldView.parentNode.replaceChild(this.render(), oldView);\r\n }\r\n }\r\n\r\n /**\r\n * Handle UL, OL and LI tags paste and returns List data\r\n * @param element - html element that contains whole list\r\n * @todo - refactor and move to list instance\r\n */\r\n public pasteHandler(element: PasteEvent['detail']['data']): ListData {\r\n const { tagName: tag } = element;\r\n let style: ListDataStyle = 'unordered';\r\n let tagToSearch: string;\r\n\r\n // set list style and tag to search.\r\n switch (tag) {\r\n case 'OL':\r\n style = 'ordered';\r\n tagToSearch = 'ol';\r\n break;\r\n case 'UL':\r\n case 'LI':\r\n style = 'unordered';\r\n tagToSearch = 'ul';\r\n }\r\n\r\n const data: ListData = {\r\n style,\r\n meta: {} as ItemMeta,\r\n items: [],\r\n };\r\n\r\n /**\r\n * Set default ordered list atributes if style is ordered\r\n */\r\n if (style === 'ordered') {\r\n (this.data.meta as OrderedListItemMeta).counterType = 'numeric';\r\n (this.data.meta as OrderedListItemMeta).start = 1;\r\n }\r\n\r\n // get pasted items from the html.\r\n const getPastedItems = (parent: Element): ListItem[] => {\r\n // get first level li elements.\r\n const children = Array.from(parent.querySelectorAll(`:scope > li`));\r\n\r\n return children.map((child) => {\r\n // get subitems if they exist.\r\n const subItemsWrapper = child.querySelector(`:scope > ${tagToSearch}`);\r\n // get subitems.\r\n const subItems = subItemsWrapper ? getPastedItems(subItemsWrapper) : [];\r\n // get text content of the li element.\r\n const content = child.innerHTML ?? '';\r\n\r\n return {\r\n content,\r\n meta: {},\r\n items: subItems,\r\n };\r\n });\r\n };\r\n\r\n // get pasted items.\r\n data.items = getPastedItems(element);\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * Changes ordered list start property value\r\n * @param index - new value of the start property\r\n */\r\n public changeStartWith(index: number): void {\r\n this.listWrapper!.style.setProperty('counter-reset', `item ${index - 1}`);\r\n\r\n (this.data.meta as OrderedListItemMeta).start = index;\r\n }\r\n\r\n /**\r\n * Changes ordered list counterType property value\r\n * @param counterType - new value of the counterType value\r\n */\r\n public changeCounters(counterType: OlCounterType): void {\r\n this.listWrapper!.style.setProperty('--list-counter-type', counterType);\r\n\r\n (this.data.meta as OrderedListItemMeta).counterType = counterType;\r\n }\r\n\r\n /**\r\n * Handles Enter keypress\r\n * @param event - keydown\r\n */\r\n private enterPressed(event: KeyboardEvent): void {\r\n const currentItem = this.currentItem;\r\n\r\n /**\r\n * Prevent editor.js behaviour\r\n */\r\n event.stopPropagation();\r\n\r\n /**\r\n * Prevent browser behaviour\r\n */\r\n event.preventDefault();\r\n\r\n /**\r\n * Prevent duplicated event in Chinese, Japanese and Korean languages\r\n */\r\n if (event.isComposing) {\r\n return;\r\n }\r\n if (currentItem === null) {\r\n return;\r\n }\r\n\r\n const isEmpty = this.renderer?.getItemContent(currentItem).trim().length === 0;\r\n const isFirstLevelItem = currentItem.parentNode === this.listWrapper;\r\n const isFirstItem = currentItem.previousElementSibling === null;\r\n\r\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\r\n\r\n /**\r\n * On Enter in the last empty item, get out of list\r\n */\r\n if (isFirstLevelItem && isEmpty) {\r\n if (isLastItem(currentItem) && !itemHasSublist(currentItem)) {\r\n /**\r\n * If current item is first and last item of the list, then empty list should be deleted after deletion of the item\r\n */\r\n if (isFirstItem) {\r\n this.convertItemToDefaultBlock(currentBlockIndex, true);\r\n } else {\r\n /**\r\n * If there are other items in the list, just remove current item and get out of the list\r\n */\r\n this.convertItemToDefaultBlock();\r\n }\r\n\r\n return;\r\n } else {\r\n /**\r\n * If enter is pressed in the сenter of the list item we should split it\r\n */\r\n this.splitList(currentItem);\r\n\r\n return;\r\n }\r\n } else if (isEmpty) {\r\n /**\r\n * If currnet item is empty and is in the middle of the list\r\n * And if current item is not on the first level\r\n * Then unshift current item\r\n */\r\n this.unshiftItem(currentItem);\r\n\r\n return;\r\n } else {\r\n /**\r\n * If current item is not empty than split current item\r\n */\r\n this.splitItem(currentItem);\r\n }\r\n }\r\n\r\n /**\r\n * Handle backspace\r\n * @param event - keydown\r\n */\r\n private backspace(event: KeyboardEvent): void {\r\n const currentItem = this.currentItem;\r\n\r\n if (currentItem === null) {\r\n return;\r\n }\r\n\r\n /**\r\n * Caret is not at start of the item\r\n * Then backspace button should remove letter as usual\r\n */\r\n if (!isCaretAtStartOfInput(currentItem)) {\r\n return;\r\n }\r\n\r\n /**\r\n * If backspace is pressed with selection, it should be handled as usual\r\n */\r\n if (window.getSelection()?.isCollapsed === false) {\r\n return;\r\n }\r\n\r\n /**\r\n * Prevent Editor.js backspace handling\r\n */\r\n event.stopPropagation();\r\n\r\n /**\r\n * First item of the list should become paragraph on backspace\r\n */\r\n if (currentItem.parentNode === this.listWrapper && currentItem.previousElementSibling === null) {\r\n /**\r\n * If current item is first item of the list, then we need to merge first item content with previous block\r\n */\r\n this.convertFirstItemToDefaultBlock();\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * Prevent default backspace behaviour\r\n */\r\n event.preventDefault();\r\n\r\n this.mergeItemWithPrevious(currentItem);\r\n }\r\n\r\n /**\r\n * Reduce indentation for current item\r\n * @param event - keydown\r\n */\r\n private shiftTab(event: KeyboardEvent): void {\r\n /**\r\n * Prevent editor.js behaviour\r\n */\r\n event.stopPropagation();\r\n\r\n /**\r\n * Prevent browser tab behaviour\r\n */\r\n event.preventDefault();\r\n\r\n /**\r\n * Check that current item exists\r\n */\r\n if (this.currentItem === null) {\r\n return;\r\n }\r\n\r\n /**\r\n * Move item from current list to parent list\r\n */\r\n this.unshiftItem(this.currentItem);\r\n }\r\n\r\n /**\r\n * Decrease indentation of the passed item\r\n * @param item - list item to be unshifted\r\n */\r\n private unshiftItem(item: ItemElement): void {\r\n if (!item.parentNode) {\r\n return;\r\n }\r\n if (!isHtmlElement(item.parentNode)) {\r\n return;\r\n }\r\n\r\n const parentItem = item.parentNode.closest<ItemElement>(`.${DefaultListCssClasses.item}`);\r\n\r\n /**\r\n * If item in the first-level list then no need to do anything\r\n */\r\n if (!parentItem) {\r\n return;\r\n }\r\n\r\n let currentItemChildWrapper = getItemChildWrapper(item);\r\n\r\n if (item.parentElement === null) {\r\n return;\r\n }\r\n\r\n const siblings = getSiblings(item);\r\n\r\n /**\r\n * If item has any siblings, they should be appended to item child wrapper\r\n */\r\n if (siblings !== null) {\r\n /**\r\n * Render child wrapper if it does no exist\r\n */\r\n if (currentItemChildWrapper === null) {\r\n currentItemChildWrapper = this.renderer.renderWrapper(false);\r\n }\r\n\r\n /**\r\n * Append siblings to item child wrapper\r\n */\r\n siblings.forEach((sibling) => {\r\n currentItemChildWrapper!.appendChild(sibling);\r\n });\r\n\r\n item.appendChild(currentItemChildWrapper);\r\n }\r\n\r\n parentItem.after(item);\r\n\r\n focusItem(item, false);\r\n\r\n /**\r\n * If parent item has empty child wrapper after unshifting of the current item, then we need to remove child wrapper\r\n * This case could be reached if the only child item of the parent was unshifted\r\n */\r\n removeChildWrapperIfEmpty(parentItem);\r\n }\r\n\r\n /**\r\n * Method that is used for list splitting and moving trailing items to the new separated list\r\n * @param item - current item html element\r\n */\r\n private splitList(item: ItemElement): void {\r\n const currentItemChildrenList = getChildItems(item);\r\n\r\n /**\r\n * Get current list block index\r\n */\r\n const currentBlock = this.block;\r\n\r\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\r\n\r\n /**\r\n * First child item should be unshifted because separated list should start\r\n * with item with first nesting level\r\n */\r\n if (currentItemChildrenList.length !== 0) {\r\n const firstChildItem = currentItemChildrenList[0];\r\n\r\n this.unshiftItem(firstChildItem);\r\n\r\n /**\r\n * If first child item was been unshifted, that caret would be set to the end of the first child item\r\n * Then we should set caret to the actual current item\r\n */\r\n focusItem(item, false);\r\n }\r\n\r\n /**\r\n * If item is first item of the list, we should just get out of the list\r\n * It means, that we would not split on two lists, if one of them would be empty\r\n */\r\n if (item.previousElementSibling === null && item.parentNode === this.listWrapper) {\r\n this.convertItemToDefaultBlock(currentBlockIndex);\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * Get trailing siblings of the current item\r\n */\r\n const newListItems = getSiblings(item);\r\n\r\n if (newListItems === null) {\r\n return;\r\n }\r\n\r\n /**\r\n * Render new wrapper for list that would be separated\r\n */\r\n const newListWrapper = this.renderer.renderWrapper(true);\r\n\r\n /**\r\n * Append new list wrapper with trailing elements\r\n */\r\n newListItems.forEach((newListItem) => {\r\n newListWrapper.appendChild(newListItem);\r\n });\r\n\r\n const newListContent = this.save(newListWrapper);\r\n\r\n (newListContent.meta as OrderedListItemMeta).start = this.data.style == 'ordered' ? 1 : undefined;\r\n\r\n /**\r\n * Insert separated list with trailing items\r\n */\r\n this.api.blocks.insert(currentBlock?.name, newListContent, this.config, currentBlockIndex + 1);\r\n\r\n /**\r\n * Insert paragraph\r\n */\r\n this.convertItemToDefaultBlock(currentBlockIndex + 1);\r\n\r\n /**\r\n * Remove temporary new list wrapper used for content save\r\n */\r\n newListWrapper.remove();\r\n }\r\n\r\n /**\r\n * Method that is used for splitting item content and moving trailing content to the new sibling item\r\n * @param currentItem - current item html element\r\n */\r\n private splitItem(currentItem: ItemElement): void {\r\n const [currentNode, offset] = getCaretNodeAndOffset();\r\n\r\n if (currentNode === null) {\r\n return;\r\n }\r\n\r\n const currentItemContent = getItemContentElement(currentItem);\r\n\r\n let endingHTML: string;\r\n\r\n /**\r\n * If current item has no content, we should pass an empty string to the next created list item\r\n */\r\n if (currentItemContent === null) {\r\n endingHTML = '';\r\n } else {\r\n /**\r\n * On other Enters, get content from caret till the end of the block\r\n * And move it to the new item\r\n */\r\n endingHTML = getContenteditableSlice(currentItemContent, currentNode, offset, 'right', true);\r\n }\r\n\r\n const itemChildren = getItemChildWrapper(currentItem);\r\n /**\r\n * Create the new list item\r\n */\r\n const itemEl = this.renderItem(endingHTML);\r\n\r\n /**\r\n * Move new item after current\r\n */\r\n currentItem?.after(itemEl);\r\n\r\n /**\r\n * If current item has children, move them to the new item\r\n */\r\n if (itemChildren) {\r\n itemEl.appendChild(itemChildren);\r\n }\r\n\r\n focusItem(itemEl);\r\n }\r\n\r\n /**\r\n * Method that is used for merging current item with previous one\r\n * Content of the current item would be appended to the previous item\r\n * Current item children would not change nesting level\r\n * @param item - current item html element\r\n */\r\n private mergeItemWithPrevious(item: ItemElement): void {\r\n const previousItem = item.previousElementSibling;\r\n\r\n const currentItemParentNode = item.parentNode;\r\n\r\n /**\r\n * Check that parent node of the current element exists\r\n */\r\n if (currentItemParentNode === null) {\r\n return;\r\n }\r\n if (!isHtmlElement(currentItemParentNode)) {\r\n return;\r\n }\r\n\r\n const parentItem = currentItemParentNode.closest<ItemElement>(`.${DefaultListCssClasses.item}`);\r\n\r\n /**\r\n * Check that current item has any previous siblings to be merged with\r\n */\r\n if (!previousItem && !parentItem) {\r\n return;\r\n }\r\n\r\n /**\r\n * Make sure previousItem is an HTMLElement\r\n */\r\n if (previousItem && !isHtmlElement(previousItem)) {\r\n return;\r\n }\r\n\r\n /**\r\n * Lets compute the item which will be merged with current item text\r\n */\r\n let targetItem: ItemElement | null;\r\n\r\n /**\r\n * If there is a previous item then we get a deepest item in its sublists\r\n *\r\n * Otherwise we will use the parent item\r\n */\r\n if (previousItem) {\r\n /**\r\n * Get list of all levels children of the previous item\r\n */\r\n const childrenOfPreviousItem = getChildItems(previousItem, false);\r\n\r\n /**\r\n * Target item would be deepest child of the previous item or previous item itself\r\n */\r\n if (childrenOfPreviousItem.length !== 0 && childrenOfPreviousItem.length !== 0) {\r\n targetItem = childrenOfPreviousItem[childrenOfPreviousItem.length - 1];\r\n } else {\r\n targetItem = previousItem;\r\n }\r\n } else {\r\n targetItem = parentItem;\r\n }\r\n\r\n /**\r\n * Get current item content\r\n */\r\n const currentItemContent = this.renderer.getItemContent(item);\r\n\r\n /**\r\n * Get the target item content element\r\n */\r\n if (!targetItem) {\r\n return;\r\n }\r\n\r\n /**\r\n * Set caret to the end of the target item\r\n */\r\n focusItem(targetItem, false);\r\n\r\n /**\r\n * Get target item content element\r\n */\r\n const targetItemContentElement = getItemContentElement(targetItem);\r\n\r\n /**\r\n * Set a new place for caret\r\n */\r\n if (targetItemContentElement === null) {\r\n return;\r\n }\r\n\r\n /**\r\n * Update target item content by merging with current item html content\r\n */\r\n targetItemContentElement.insertAdjacentHTML('beforeend', currentItemContent);\r\n\r\n /**\r\n * Get child list of the currentItem\r\n */\r\n const currentItemChildrenList = getChildItems(item);\r\n\r\n /**\r\n * If item has no children, just remove item\r\n * Else children of the item should be prepended to the target item child list\r\n */\r\n if (currentItemChildrenList.length === 0) {\r\n /**\r\n * Remove current item element\r\n */\r\n item.remove();\r\n\r\n /**\r\n * If target item has empty child wrapper after merge, we need to remove child wrapper\r\n * This case could be reached if the only child item of the target was merged with target\r\n */\r\n removeChildWrapperIfEmpty(targetItem);\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * Get target for child list of the currentItem\r\n * Note that previous item and parent item could not be null at the same time\r\n * This case is checked before\r\n */\r\n const targetForChildItems = previousItem ? previousItem : parentItem!;\r\n\r\n const targetChildWrapper = getItemChildWrapper(targetForChildItems) ?? this.renderer.renderWrapper(false);\r\n\r\n /**\r\n * Add child current item children to the target childWrapper\r\n */\r\n if (previousItem) {\r\n currentItemChildrenList.forEach((childItem) => {\r\n targetChildWrapper.appendChild(childItem);\r\n });\r\n } else {\r\n currentItemChildrenList.forEach((childItem) => {\r\n targetChildWrapper.prepend(childItem);\r\n });\r\n }\r\n\r\n /**\r\n * If we created new wrapper, then append childWrapper to the target item\r\n */\r\n if (getItemChildWrapper(targetForChildItems) === null) {\r\n targetItem.appendChild(targetChildWrapper);\r\n }\r\n\r\n /**\r\n * Remove current item element\r\n */\r\n item.remove();\r\n }\r\n\r\n /**\r\n * Add indentation to current item\r\n * @param event - keydown\r\n */\r\n private addTab(event: KeyboardEvent): void {\r\n /**\r\n * Prevent editor.js behaviour\r\n */\r\n event.stopPropagation();\r\n\r\n /**\r\n * Prevent browser tab behaviour\r\n */\r\n event.preventDefault();\r\n\r\n const currentItem = this.currentItem;\r\n\r\n if (!currentItem) {\r\n return;\r\n }\r\n\r\n /**\r\n * Check that maxLevel specified in config\r\n */\r\n if (this.config?.maxLevel !== undefined) {\r\n const currentItemLevel = this.currentItemLevel;\r\n\r\n /**\r\n * Check that current item is not in the maximum nesting level\r\n */\r\n if (currentItemLevel !== null && currentItemLevel === this.config.maxLevel) {\r\n return;\r\n }\r\n }\r\n\r\n /**\r\n * Check that the item has potential parent\r\n * Previous sibling is potential parent in case of adding tab\r\n * After adding tab current item would be moved to the previous sibling's child list\r\n */\r\n const prevItem = currentItem.previousSibling;\r\n\r\n if (prevItem === null) {\r\n return;\r\n }\r\n if (!isHtmlElement(prevItem)) {\r\n return;\r\n }\r\n\r\n const prevItemChildrenList = getItemChildWrapper(prevItem);\r\n\r\n /**\r\n * If prev item has child items, just append current to them\r\n * Else render new child wrapper for previous item\r\n */\r\n if (prevItemChildrenList) {\r\n /**\r\n * Previous item would be appended with current item and it's sublists\r\n * After that sublists would be moved one level back\r\n */\r\n prevItemChildrenList.appendChild(currentItem);\r\n\r\n /**\r\n * Get all current item child to be moved to previous nesting level\r\n */\r\n const currentItemChildrenList = getChildItems(currentItem);\r\n\r\n /**\r\n * Move current item sublists one level back\r\n */\r\n currentItemChildrenList.forEach((child) => {\r\n prevItemChildrenList.appendChild(child);\r\n });\r\n } else {\r\n const prevItemChildrenListWrapper = this.renderer.renderWrapper(false);\r\n\r\n /**\r\n * Previous item would be appended with current item and it's sublists\r\n * After that sublists would be moved one level back\r\n */\r\n prevItemChildrenListWrapper.appendChild(currentItem);\r\n\r\n /**\r\n * Get all current item child to be moved to previous nesting level\r\n */\r\n const currentItemChildrenList = getChildItems(currentItem);\r\n\r\n /**\r\n * Move current item sublists one level back\r\n */\r\n currentItemChildrenList.forEach((child) => {\r\n prevItemChildrenListWrapper.appendChild(child);\r\n });\r\n\r\n prevItem.appendChild(prevItemChildrenListWrapper);\r\n }\r\n\r\n /**\r\n * Remove child wrapper of the current item if it is empty after adding the tab\r\n * This case would be reached, because after adding tab current item will have same nesting level with children\r\n * So its child wrapper would be empty\r\n */\r\n removeChildWrapperIfEmpty(currentItem);\r\n\r\n focusItem(currentItem, false);\r\n }\r\n\r\n /**\r\n * Convert current item to default block with passed index\r\n * @param newBloxkIndex - optional parameter represents index, where would be inseted default block\r\n * @param removeList - optional parameter, that represents condition, if List should be removed\r\n */\r\n private convertItemToDefaultBlock(newBloxkIndex?: number, removeList?: boolean): void {\r\n let newBlock;\r\n\r\n const currentItem = this.currentItem;\r\n\r\n const currentItemContent = currentItem !== null ? this.renderer.getItemContent(currentItem) : '';\r\n\r\n if (removeList === true) {\r\n this.api.blocks.delete();\r\n }\r\n\r\n /**\r\n * Check that index have passed\r\n */\r\n if (newBloxkIndex !== undefined) {\r\n newBlock = this.api.blocks.insert(undefined, { text: currentItemContent }, undefined, newBloxkIndex);\r\n } else {\r\n newBlock = this.api.blocks.insert();\r\n }\r\n\r\n currentItem?.remove();\r\n this.api.caret.setToBlock(newBlock, 'start');\r\n }\r\n\r\n /**\r\n * Convert first item of the list to default block\r\n * This method could be called when backspace button pressed at start of the first item of the list\r\n * First item of the list would be converted to the paragraph and first item children would be unshifted\r\n */\r\n private convertFirstItemToDefaultBlock(): void {\r\n const currentItem = this.currentItem;\r\n\r\n if (currentItem === null) {\r\n return;\r\n }\r\n\r\n const currentItemChildren = getChildItems(currentItem);\r\n\r\n /**\r\n * Check that current item have at least one child\r\n * If current item have no children, we can guarantee,\r\n * that after deletion of the first item of the list, children would not be removed\r\n */\r\n if (currentItemChildren.length !== 0) {\r\n const firstChildItem = currentItemChildren[0];\r\n\r\n /**\r\n * Unshift first child item, to guarantee, that after deletion of the first item\r\n * list will start with first level of nesting\r\n */\r\n this.unshiftItem(firstChildItem);\r\n\r\n /**\r\n * Set focus back to the current item after unshifting child\r\n */\r\n focusItem(currentItem);\r\n }\r\n\r\n /**\r\n * Get all first level items of the list\r\n */\r\n const currentItemSiblings = getSiblings(currentItem);\r\n\r\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\r\n\r\n /**\r\n * If current item has no siblings, than List is empty, and it should be deleted\r\n */\r\n const removeList = currentItemSiblings === null;\r\n\r\n this.convertItemToDefaultBlock(currentBlockIndex, removeList);\r\n }\r\n\r\n /**\r\n * Method that calls render function of the renderer with a necessary item meta cast\r\n * @param itemContent - content to be rendered in new item\r\n * @param meta - meta used in list item rendering\r\n * @returns html element of the rendered item\r\n */\r\n private renderItem(itemContent: ListItem['content'], meta?: ListItem['meta']): ItemElement {\r\n const itemMeta = meta ?? this.renderer.composeDefaultMeta();\r\n\r\n switch (true) {\r\n case this.renderer instanceof OrderedListRenderer:\r\n return this.renderer.renderItem(itemContent, itemMeta as OrderedListItemMeta);\r\n\r\n case this.renderer instanceof UnorderedListRenderer:\r\n return this.renderer.renderItem(itemContent, itemMeta as UnorderedListItemMeta);\r\n\r\n default:\r\n return this.renderer.renderItem(itemContent, itemMeta as ChecklistItemMeta);\r\n }\r\n }\r\n\r\n /**\r\n * Renders children list\r\n * @param items - list data used in item rendering\r\n * @param parentElement - where to append passed items\r\n */\r\n private appendItems(items: ListItem[], parentElement: Element): void {\r\n items.forEach((item) => {\r\n const itemEl = this.renderItem(item.content, item.meta);\r\n\r\n parentElement.appendChild(itemEl);\r\n\r\n /**\r\n * Check if there are child items\r\n */\r\n if (item.items.length) {\r\n const sublistWrapper = this.renderer?.renderWrapper(false);\r\n\r\n /**\r\n * Recursively render child items\r\n */\r\n this.appendItems(item.items, sublistWrapper);\r\n\r\n itemEl.appendChild(sublistWrapper);\r\n }\r\n });\r\n }\r\n}\r\n","import type { ItemElement } from '../types/Elements';\r\n\r\n/**\r\n * Check that passed item element is last item of the list\r\n * @param item - item to be checked, wherever it has next element sibling\r\n */\r\nexport function isLastItem(item: ItemElement): boolean {\r\n return item.nextElementSibling === null;\r\n}\r\n","import type { ItemElement } from '../types/Elements';\r\nimport { DefaultListCssClasses } from '../ListRenderer';\r\n\r\n/**\r\n * Check if passed item has the sublist\r\n * @param item - item to be checked wherever it has sublist\r\n */\r\nexport function itemHasSublist(item: ItemElement): boolean {\r\n return item.querySelector(`.${DefaultListCssClasses.itemChildren}`) !== null;\r\n}\r\n","import { IconNumber, IconLowerRoman, IconUpperRoman, IconLowerAlpha, IconUpperAlpha } from '../../../icons';\r\n\r\nexport type OlCounterType = 'numeric' | 'upper-roman' | 'lower-roman' | 'upper-alpha' | 'lower-alpha';\r\n\r\n/**\r\n * Map that represents all of the supported styles of the counters for ordered list\r\n */\r\nexport const OlCounterTypesMap = new Map<string, string>([\r\n /**\r\n * Value that represents default arabic numbers for counters\r\n */\r\n ['Numeric', 'numeric'],\r\n\r\n /**\r\n * Value that represents lower roman numbers for counteres\r\n */\r\n ['Lower Roman', 'lower-roman'],\r\n\r\n /**\r\n * Value that represents upper roman numbers for counters\r\n */\r\n ['Upper Roman', 'upper-roman'],\r\n\r\n /**\r\n * Value that represents lower alpha characters for counters\r\n */\r\n ['Lower Alpha', 'lower-alpha'],\r\n\r\n /**\r\n * Value that represents upper alpha characters for counters\r\n */\r\n ['Upper Alpha', 'upper-alpha'],\r\n]);\r\n\r\n/**\r\n * Map that represents relation between supported counter types and theirs icons to be displayed in toolbox\r\n */\r\nexport const OlCounterIconsMap = new Map<string, string>([\r\n /**\r\n * Value that represents Icon for Numeric counter type\r\n */\r\n ['numeric', IconNumber],\r\n\r\n /**\r\n * Value that represents Icon for Lower Roman counter type\r\n */\r\n ['lower-roman', IconLowerRoman],\r\n\r\n /**\r\n * Value that represents Icon for Upper Roman counter type\r\n */\r\n ['upper-roman', IconUpperRoman],\r\n\r\n /**\r\n * Value that represents Icon for Lower Alpha counter type\r\n */\r\n ['lower-alpha', IconLowerAlpha],\r\n\r\n /**\r\n * Value that represents Icon for Upper Alpha counter type\r\n */\r\n ['upper-alpha', IconUpperAlpha],\r\n]);\r\n","import type { API, BlockAPI, PasteConfig, ToolboxConfig } from '@ebl-vue/editorjs';\r\nimport type {\r\n BlockToolConstructorOptions,\r\n \r\n ToolConfig\r\n} from '@editorjs/editorjs/types/tools';\r\n\r\n\r\nimport type { ListConfig, ListData, ListDataStyle, ListItem, OldListData } from './types/ListParams';\r\nimport ListTabulator from './ListTabulator';\r\nimport { CheckListRenderer, OrderedListRenderer, UnorderedListRenderer } from './ListRenderer';\r\nimport type { ListRenderer } from './types/ListRenderer';\r\n\r\nimport { type OlCounterType, OlCounterTypesMap } from './types/OlCounterType';\r\n\r\nimport { IconListBulleted, IconListNumbered, IconChecklist } from \"../../icons\"; \r\n\r\n\r\n\r\n/**\r\n * Build styles\r\n */\r\nimport './styles/list.css';\r\nimport './styles/input.css';\r\n\r\nimport normalizeData from './utils/normalizeData';\r\nimport type { PasteEvent } from './types';\r\nimport type { OrderedListItemMeta } from './types/ItemMeta';\r\n\r\n/**\r\n * Constructor Params for Editorjs List Tool, use to pass initial data and settings\r\n */\r\nexport type ListParams = BlockToolConstructorOptions<ListData | OldListData, ListConfig>;\r\n\r\n/**\r\n * Default class of the component used in editor\r\n */\r\nexport default class EditorjsList {\r\n defaultCounterTypes: OlCounterType[];\r\n /**\r\n * Notify core that read-only mode is supported\r\n */\r\n public static get isReadOnlySupported(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Allow to use native Enter behaviour\r\n */\r\n public static get enableLineBreaks(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n */\r\n public static get toolbox(): ToolboxConfig {\r\n return [\r\n {\r\n icon: IconListBulleted,\r\n title: 'Unordered List',\r\n data: {\r\n style: 'unordered',\r\n },\r\n },\r\n {\r\n icon: IconListNumbered,\r\n title: 'Ordered List',\r\n data: {\r\n style: 'ordered',\r\n },\r\n },\r\n {\r\n icon: IconChecklist,\r\n title: 'Checklist',\r\n data: {\r\n style: 'checklist',\r\n },\r\n },\r\n ];\r\n }\r\n\r\n /**\r\n * On paste sanitzation config. Allow only tags that are allowed in the Tool.\r\n * @returns - paste config object used in editor\r\n */\r\n public static get pasteConfig(): PasteConfig {\r\n return {\r\n tags: ['OL', 'UL', 'LI'],\r\n };\r\n }\r\n\r\n /**\r\n * Convert from text to list with import and export list to text\r\n */\r\n public static get conversionConfig(): {\r\n /**\r\n * Method that is responsible for conversion from data to string\r\n * @param data - current list data\r\n * @returns - contents string formed from list data\r\n */\r\n export: (data: ListData) => string;\r\n\r\n /**\r\n * Method that is responsible for conversion from string to data\r\n * @param content - contents string\r\n * @returns - list data formed from contents string\r\n */\r\n import: (content: string, config: ToolConfig<ListConfig>) => ListData;\r\n } {\r\n return {\r\n export: (data) => {\r\n return EditorjsList.joinRecursive(data);\r\n },\r\n import: (content, config) => {\r\n return {\r\n meta: {},\r\n items: [\r\n {\r\n content,\r\n meta: {},\r\n items: [],\r\n },\r\n ],\r\n style: config?.defaultStyle !== undefined ? config.defaultStyle : 'unordered',\r\n };\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Get list style name\r\n */\r\n private get listStyle(): ListDataStyle {\r\n return this.data.style || this.defaultListStyle;\r\n }\r\n\r\n /**\r\n * Set list style\r\n * @param style - new style to set\r\n */\r\n private set listStyle(style: ListDataStyle) {\r\n this.data.style = style;\r\n\r\n this.changeTabulatorByStyle();\r\n\r\n /**\r\n * Create new list element\r\n */\r\n const newListElement = this.list!.render();\r\n\r\n this.listElement?.replaceWith(newListElement);\r\n\r\n this.listElement = newListElement;\r\n }\r\n\r\n /**\r\n * The Editor.js API\r\n */\r\n private api: API;\r\n\r\n /**\r\n * Is Ediotrjs List Tool read-only\r\n */\r\n private readOnly: boolean;\r\n\r\n /**\r\n * Tool's configuration\r\n */\r\n private config: ListConfig | undefined;\r\n\r\n /**\r\n * Default list style formes as passed default list style from config or 'ordered' as default\r\n */\r\n private defaultListStyle?: ListConfig['defaultStyle'];\r\n\r\n /**\r\n * Default Counter type of the ordered list\r\n */\r\n //private defaultCounterTypes: OlCounterType[];\r\n\r\n /**\r\n * Tool's data\r\n */\r\n private data: ListData;\r\n\r\n /**\r\n * Editor block api\r\n */\r\n private block: BlockAPI;\r\n\r\n /**\r\n * Class that is responsible for complete list rendering and saving\r\n */\r\n private list: ListTabulator<ListRenderer> | undefined;\r\n\r\n /**\r\n * Main constant wrapper of the whole list\r\n */\r\n private listElement: HTMLElement | undefined;\r\n\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n * @param params - tool constructor options\r\n * @param params.data - previously saved data\r\n * @param params.config - user config for Tool\r\n * @param params.api - Editor.js API\r\n * @param params.readOnly - read-only mode flag\r\n */\r\n constructor({ data, config, api, readOnly, block }: ListParams) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n this.config = config;\r\n this.block = block;\r\n\r\n /**\r\n * Set the default list style from the config or presetted 'unordered'.\r\n */\r\n this.defaultListStyle = this.config?.defaultStyle || 'unordered';\r\n\r\n /**\r\n * Set the default counter types for the ordered list\r\n */\r\n this.defaultCounterTypes = (this.config as ListConfig).counterTypes || Array.from(OlCounterTypesMap.values()) as OlCounterType[];\r\n\r\n const initialData = {\r\n style: this.defaultListStyle,\r\n meta: {},\r\n items: [],\r\n };\r\n\r\n this.data = Object.keys(data).length ? normalizeData(data) : initialData;\r\n\r\n /**\r\n * Assign default value of the property for the ordered list\r\n */\r\n if (this.listStyle === 'ordered' && (this.data.meta as OrderedListItemMeta).counterType === undefined) {\r\n (this.data.meta as OrderedListItemMeta).counterType = 'numeric';\r\n }\r\n\r\n this.changeTabulatorByStyle();\r\n }\r\n\r\n /**\r\n * Convert from list to text for conversionConfig\r\n * @param data - current data of the list\r\n * @returns - string of the recursively merged contents of the items of the list\r\n */\r\n private static joinRecursive(data: ListData | ListItem): string {\r\n return data.items\r\n .map(item => `${item.content} ${EditorjsList.joinRecursive(item)}`)\r\n .join('');\r\n }\r\n\r\n /**\r\n * Function that is responsible for content rendering\r\n * @returns rendered list wrapper with all contents\r\n */\r\n public render(): HTMLElement {\r\n this.listElement = this.list!.render();\r\n\r\n return this.listElement;\r\n }\r\n\r\n /**\r\n * Function that is responsible for content saving\r\n * @returns formatted content used in editor\r\n */\r\n public save(): ListData {\r\n this.data = this.list!.save();\r\n\r\n return this.data;\r\n }\r\n\r\n /**\r\n * Function that is responsible for mergind two lists into one\r\n * @param data - data of the next standing list, that should be merged with current\r\n */\r\n public merge(data: ListData): void {\r\n this.list!.merge(data);\r\n }\r\n\r\n /**\r\n * Creates Block Tune allowing to change the list style\r\n * @returns array of tune configs\r\n */\r\n // public renderSettings(): MenuConfigItem[] {\r\n // const defaultTunes: MenuConfigItem[] = [\r\n // {\r\n // label: this.api.i18n.t('Unordered'),\r\n // icon: IconListBulleted,\r\n // closeOnActivate: true,\r\n // isActive: this.listStyle == 'unordered',\r\n // onActivate: () => {\r\n // this.listStyle = 'unordered';\r\n // },\r\n // },\r\n // {\r\n // label: this.api.i18n.t('Ordered'),\r\n // icon: IconListNumbered,\r\n // closeOnActivate: true,\r\n // isActive: this.listStyle == 'ordered',\r\n // onActivate: () => {\r\n // this.listStyle = 'ordered';\r\n // },\r\n // },\r\n // {\r\n // label: this.api.i18n.t('Checklist'),\r\n // icon: IconChecklist,\r\n // closeOnActivate: true,\r\n // isActive: this.listStyle == 'checklist',\r\n // onActivate: () => {\r\n // this.listStyle = 'checklist';\r\n // },\r\n // },\r\n // ];\r\n\r\n // if (this.listStyle === 'ordered') {\r\n // const startWithElement = renderToolboxInput(\r\n // (index: string) => this.changeStartWith(Number(index)),\r\n // {\r\n // value: String((this.data.meta as OrderedListItemMeta).start ?? 1),\r\n // placeholder: '',\r\n // attributes: {\r\n // required: 'true',\r\n // },\r\n // sanitize: input => stripNumbers(input),\r\n // });\r\n\r\n // const orderedListTunes: MenuConfigItem[] = [\r\n // {\r\n // label: this.api.i18n.t('Start with'),\r\n // icon: IconStartWith,\r\n // children: {\r\n // items: [\r\n // {\r\n // element: startWithElement,\r\n // // @ts-expect-error ts(2820) can not use PopoverItem enum from editor.js types\r\n // type: 'html',\r\n // },\r\n // ],\r\n // },\r\n // },\r\n // ];\r\n\r\n // const orderedListCountersTunes: MenuConfigItem = {\r\n // label: this.api.i18n.t('Counter type'),\r\n // icon: OlCounterIconsMap.get((this.data.meta as OrderedListItemMeta).counterType!),\r\n // children: {\r\n // items: [],\r\n // },\r\n // };\r\n\r\n // /**\r\n // * For each counter type in OlCounterType create toolbox item\r\n // */\r\n // OlCounterTypesMap.forEach((_, counterType: string) => {\r\n // const counterTypeValue = OlCounterTypesMap.get(counterType)! as OlCounterType;\r\n\r\n // if (!this.defaultCounterTypes.includes(counterTypeValue)) {\r\n // return;\r\n // }\r\n\r\n // orderedListCountersTunes.children.items!.push({\r\n // title: this.api.i18n.t(counterType),\r\n // icon: OlCounterIconsMap.get(counterTypeValue),\r\n // isActive: (this.data.meta as OrderedListItemMeta).counterType === OlCounterTypesMap.get(counterType),\r\n // closeOnActivate: true,\r\n // onActivate: () => {\r\n // this.changeCounters(OlCounterTypesMap.get(counterType) as OlCounterType);\r\n // },\r\n // });\r\n // });\r\n\r\n // /**\r\n // * Dont show Counter type tune if there is no valid counter types\r\n // */\r\n // if (orderedListCountersTunes.children.items!.length > 1) {\r\n // orderedListTunes.push(orderedListCountersTunes);\r\n // }\r\n\r\n // // @ts-expect-error ts(2820) can not use PopoverItem enum from editor.js types\r\n // defaultTunes.push({ type: 'separator' }, ...orderedListTunes);\r\n // }\r\n\r\n // return defaultTunes;\r\n // }\r\n\r\n /**\r\n * On paste callback that is fired from Editor.\r\n * @param event - event with pasted data\r\n */\r\n public onPaste(event: PasteEvent): void {\r\n const { tagName: tag } = event.detail.data;\r\n\r\n switch (tag) {\r\n case 'OL':\r\n this.listStyle = 'ordered';\r\n break;\r\n case 'UL':\r\n case 'LI':\r\n this.listStyle = 'unordered';\r\n }\r\n\r\n this.list!.onPaste(event);\r\n }\r\n\r\n /**\r\n * Handle UL, OL and LI tags paste and returns List data\r\n * @param element - html element that contains whole list\r\n */\r\n public pasteHandler(element: PasteEvent['detail']['data']): ListData {\r\n const data = this.list!.pasteHandler(element);\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * Changes ordered list counterType property value\r\n * @param counterType - new value of the counterType value\r\n */\r\n // private changeCounters(counterType: OlCounterType): void {\r\n // this.list?.changeCounters(counterType);\r\n\r\n // (this.data.meta as OrderedListItemMeta).counterType = counterType;\r\n // }\r\n\r\n /**\r\n * Changes ordered list start property value\r\n * @param index - new value of the start property\r\n // */\r\n // private changeStartWith(index: number): void {\r\n // this.list?.changeStartWith(index);\r\n\r\n // (this.data.meta as OrderedListItemMeta).start = index;\r\n // }\r\n\r\n /**\r\n * This method allows changing tabulator respectfully to passed style\r\n */\r\n private changeTabulatorByStyle(): void {\r\n switch (this.listStyle) {\r\n case 'ordered':\r\n this.list = new ListTabulator<OrderedListRenderer>({\r\n data: this.data,\r\n readOnly: this.readOnly,\r\n api: this.api,\r\n config: this.config,\r\n block: this.block,\r\n },\r\n new OrderedListRenderer(this.readOnly, this.config)\r\n );\r\n\r\n break;\r\n\r\n case 'unordered':\r\n this.list = new ListTabulator<UnorderedListRenderer>({\r\n data: this.data,\r\n readOnly: this.readOnly,\r\n api: this.api,\r\n config: this.config,\r\n block: this.block,\r\n },\r\n new UnorderedListRenderer(this.readOnly, this.config)\r\n );\r\n\r\n break;\r\n\r\n case 'checklist':\r\n this.list = new ListTabulator<CheckListRenderer>({\r\n data: this.data,\r\n readOnly: this.readOnly,\r\n api: this.api,\r\n config: this.config,\r\n block: this.block,\r\n },\r\n new CheckListRenderer(this.readOnly, this.config)\r\n );\r\n\r\n break;\r\n }\r\n }\r\n}\r\n","import type { OldListData, ListData, ListItem, OldChecklistData, OldNestedListData } from '../types/ListParams';\r\n\r\n/**\r\n * Method that checks if data is result of the Old list tool save mtehod\r\n * @param data - data of the OldList, Checklist, OldNestedList or Editorjs List tool\r\n * @returns true if data related to the List tool, false otherwise\r\n */\r\nfunction instanceOfOldListData(data: ListData | OldListData | OldChecklistData | OldNestedListData): data is OldListData {\r\n return (typeof data.items[0] === 'string');\r\n}\r\n\r\n/**\r\n * Method that checks if data is result of the Old nested list tool save method\r\n * @param data - data of the OldList, Checklist, OldNestedList or Editorjs List tool\r\n * @returns true if data is related to the Nested List tool, false otherwise\r\n */\r\nfunction instanceOfOldNestedListData(data: ListData | OldListData | OldChecklistData | OldNestedListData): data is OldNestedListData {\r\n return !('meta' in data);\r\n}\r\n\r\n/**\r\n * Method that checks if data is result of the Old checklist tool save method\r\n * @param data - data of the Checklist, OldList, OldNestedList or Editorjs List tool\r\n * @returns true if data is related to the Checklist tool, false otherwise\r\n */\r\nfunction instanceOfChecklistData(data: ListData | OldListData | OldChecklistData | OldNestedListData): data is OldChecklistData {\r\n return (\r\n typeof data.items[0] !== 'string'\r\n && 'text' in data.items[0]\r\n && 'checked' in data.items[0]\r\n && typeof data.items[0].text === 'string'\r\n && typeof data.items[0].checked === 'boolean'\r\n );\r\n}\r\n\r\n/**\r\n * Method that checks if passed data is related to the legacy format and normalizes it\r\n * @param data - data to be checked\r\n * @returns - normalized data, ready to be used by Editorjs List tool\r\n */\r\nexport default function normalizeData(data: ListData | OldListData | OldChecklistData): ListData {\r\n\r\n const normalizedDataItems: ListItem[] = [];\r\n\r\n if (instanceOfOldListData(data)) {\r\n data.items.forEach((item) => {\r\n normalizedDataItems.push({\r\n content: item,\r\n meta: {},\r\n items: [],\r\n });\r\n });\r\n\r\n return {\r\n style: data.style,\r\n meta: {},\r\n items: normalizedDataItems,\r\n };\r\n } else if (instanceOfChecklistData(data)) {\r\n data.items.forEach((item) => {\r\n normalizedDataItems.push({\r\n content: item.text,\r\n meta: {\r\n checked: item.checked,\r\n },\r\n items: [],\r\n });\r\n });\r\n\r\n return {\r\n style: 'checklist',\r\n meta: {},\r\n items: normalizedDataItems,\r\n };\r\n } else if (instanceOfOldNestedListData(data)) {\r\n return {\r\n style: data.style,\r\n meta: {},\r\n items: data.items,\r\n };\r\n } else {\r\n return structuredClone(data);\r\n }\r\n};\r\n","/**\r\n * @typedef {Object} Observer\r\n * @description Custom MutationObserver to detect changes in the editor.\r\n * @property {String} holder — Editor.js holder id.\r\n * @property {Object} observer - MutationObserver object that detects changes in the editor.\r\n * @property {Number} debounceTimer - Delay time for the debouncer.\r\n * @property {Function} mutationDebouncer - Debouncer to delay the changes registration.\r\n */\r\nexport default class Observer {\r\n private observer: MutationObserver | null;\r\n private debounceTimer: number;\r\n private mutationDebouncer: Function;\r\n private holder: HTMLElement;\r\n /**\r\n * Creates a new instance of the Observer object.\r\n * @param {Function} registerChange - Function that register a change in the history stack.\r\n * @param {String} holder - Editor.js holder id.\r\n * @param {Number} debounceTimer Delay time for the debouncer.\r\n */\r\n constructor(registerChange: Function, holder: HTMLElement, debounceTimer: number) {\r\n\r\n this.holder = holder;\r\n this.observer = null;\r\n this.debounceTimer = debounceTimer;\r\n this.mutationDebouncer = this.debounce(() => {\r\n registerChange();\r\n }, this.debounceTimer);\r\n }\r\n\r\n /**\r\n * Sets a mutation observer to catch every change in the editor.\r\n */\r\n setMutationObserver() {\r\n const observerOptions = {\r\n childList: true,\r\n attributes: true,\r\n subtree: true,\r\n characterData: true,\r\n characterDataOldValue: true,\r\n };\r\n\r\n const target = this.holder.querySelector('.codex-editor__redactor') as HTMLElement;\r\n\r\n this.observer = new MutationObserver((mutationList) => {\r\n this.mutationHandler(mutationList);\r\n });\r\n this.observer.observe(target, observerOptions);\r\n }\r\n\r\n /**\r\n * Handles the mutations and checks if a new mutation has been produced.\r\n * @param {Object} mutationList The registered mutations\r\n */\r\n mutationHandler(mutationList: any[]) {\r\n let contentMutated = false;\r\n\r\n mutationList.forEach((mutation:any) => {\r\n switch (mutation.type) {\r\n case 'childList':\r\n if (mutation.target === this.holder) {\r\n this.onDestroy();\r\n } else {\r\n contentMutated = true;\r\n }\r\n break;\r\n case 'characterData':\r\n contentMutated = true;\r\n break;\r\n case 'attributes':\r\n if (!mutation.target.classList.contains('ce-block') && !mutation.target.classList.contains('tc-toolbox')) {\r\n contentMutated = true;\r\n }\r\n break;\r\n default:\r\n break;\r\n }\r\n });\r\n\r\n if (contentMutated) this.mutationDebouncer();\r\n }\r\n\r\n /**\r\n * Delays invoking a function until after wait millis have elapsed.\r\n * @param {Function} callback The function to be delayed.\r\n * @param {Number} wait The deplay time in millis.\r\n */\r\n debounce(callback: Function, wait: number) {\r\n let timeout: any;\r\n return (...args:any) => {\r\n const context = this;\r\n clearTimeout(timeout);\r\n timeout = setTimeout(() => callback.apply(context, args), wait);\r\n };\r\n }\r\n\r\n onDestroy() {\r\n const destroyEvent = new CustomEvent('destroy');\r\n document.dispatchEvent(destroyEvent);\r\n this.observer?.disconnect();\r\n }\r\n}\r\n","import VanillaCaret from \"vanilla-caret-js\";\r\nimport Observer from \"./observer\";\r\nimport type EditorJS from '@ebl-vue/editorjs';\r\n\r\n/**\r\n * https://github.com/kommitters/editorjs-undo/tree/main\r\n * Undo/Redo feature for Editor.js.\r\n *\r\n * @typedef {Object} Undo\r\n * @description Feature's initialization class.\r\n * @property {Object} editor — Editor.js instance object.\r\n * @property {Number} maxLength - Max amount of changes recorded by the history stack.\r\n * @property {Function} onUpdate - Callback called when the user performs an undo or redo action.\r\n * @property {Boolean} shouldSaveHistory - Defines if the plugin should save the change in the stack\r\n * @property {Object} initialItem - Initial data object.\r\n */\r\nexport default class Undo {\r\n editor: EditorJS | null;\r\n holder: any;\r\n defaultBlock: any;\r\n blocks: any;\r\n caret: any;\r\n shouldSaveHistory: boolean;\r\n readOnly: any;\r\n maxLength: any;\r\n onUpdate: any;\r\n config: { debounceTimer: any; shortcuts: { undo: any; redo: any; }; };\r\n initialItem: any;\r\n stack: any;\r\n position: number=0;\r\n /**\r\n * @param options — Plugin custom options.\r\n */\r\n constructor({ editor, config = {}, onUpdate, maxLength }:{ editor: EditorJS, config?: any, onUpdate?: any, maxLength?: any }) {\r\n const defaultOptions = {\r\n maxLength: 30,\r\n onUpdate() {},\r\n config: {\r\n debounceTimer: 200,\r\n shortcuts: {\r\n undo: [\"CMD+Z\"],\r\n redo: [\"CMD+Y\", \"CMD+SHIFT+Z\"],\r\n },\r\n },\r\n };\r\n\r\n const { blocks, caret } = editor;\r\n const { configuration } = editor;\r\n const { holder, defaultBlock } = configuration;\r\n const defaultShortcuts = defaultOptions.config.shortcuts;\r\n const { shortcuts: configShortcuts } = config;\r\n const shortcuts = { ...defaultShortcuts, ...configShortcuts };\r\n const undo = Array.isArray(shortcuts.undo) ? shortcuts.undo : [shortcuts.undo];\r\n const redo = Array.isArray(shortcuts.redo) ? shortcuts.redo : [shortcuts.redo];\r\n const defaultDebounceTimer = defaultOptions.config.debounceTimer;\r\n const { debounceTimer = defaultDebounceTimer } = config;\r\n\r\n this.holder =\r\n typeof holder === \"string\" ? document.getElementById(holder) : holder;\r\n this.editor = editor;\r\n this.defaultBlock = defaultBlock;\r\n this.blocks = blocks;\r\n this.caret = caret;\r\n this.shouldSaveHistory = true;\r\n this.readOnly = configuration.readOnly;\r\n this.maxLength = maxLength || defaultOptions.maxLength;\r\n this.onUpdate = onUpdate || defaultOptions.onUpdate;\r\n this.config = { debounceTimer, shortcuts: { undo, redo } };\r\n\r\n const observer = new Observer(\r\n () => this.registerChange(),\r\n this.holder,\r\n this.config.debounceTimer\r\n );\r\n observer.setMutationObserver();\r\n\r\n this.setEventListeners();\r\n this.initialItem = null;\r\n this.clear();\r\n }\r\n\r\n /**\r\n * Notify core that read-only mode is suppoorted\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Truncates the history stack when it excedes the limit of changes.\r\n *\r\n * @param {Object} stack Changes history stack.\r\n * @param {Number} stack Limit of changes recorded by the history stack.\r\n */\r\n truncate(stack: any, limit: number) {\r\n while (stack.length > limit) {\r\n stack.shift();\r\n }\r\n }\r\n\r\n /**\r\n * Initializes the stack when the user provides initial data.\r\n *\r\n * @param {Object} initialItem Initial data provided by the user.\r\n */\r\n initialize(initialItem: any) {\r\n const initialData =\r\n \"blocks\" in initialItem ? initialItem.blocks : initialItem;\r\n const initialIndex = initialData.length - 1;\r\n const firstElement = { index: initialIndex, state: initialData };\r\n this.stack[0] = firstElement;\r\n this.initialItem = firstElement;\r\n }\r\n\r\n /**\r\n * Clears the history stack.\r\n */\r\n clear() {\r\n this.stack = this.initialItem\r\n ? [this.initialItem]\r\n : [{ index: 0, state: [{ type: this.defaultBlock, data: {} }] }];\r\n this.position = 0;\r\n this.onUpdate();\r\n }\r\n\r\n /**\r\n * Returns true if readOnly was toggled to true\r\n * @returns {Node} Indirectly shows if readOnly was set to true or false\r\n */\r\n setReadOnly() {\r\n const toolbox = this.holder.querySelector(\".ce-toolbox\");\r\n this.readOnly = !toolbox;\r\n }\r\n\r\n /**\r\n * Registers the data returned by API's save method into the history stack.\r\n */\r\n registerChange() {\r\n this.setReadOnly();\r\n if (!this.readOnly) {\r\n if (this.editor && this.editor.save && this.shouldSaveHistory) {\r\n this.editor.save().then((savedData) => {\r\n if (this.editorDidUpdate(savedData.blocks))\r\n this.save(savedData.blocks);\r\n });\r\n }\r\n this.shouldSaveHistory = true;\r\n }\r\n }\r\n\r\n /**\r\n * Checks if the saved data has to be added to the history stack.\r\n *\r\n * @param {Object} newData New data to be saved in the history stack.\r\n * @returns {Boolean}\r\n */\r\n editorDidUpdate(newData: any) {\r\n const { state } = this.stack[this.position];\r\n if (!newData.length) return false;\r\n if (newData.length !== state.length) return true;\r\n\r\n return JSON.stringify(state) !== JSON.stringify(newData);\r\n }\r\n\r\n /**\r\n * Adds the saved data in the history stack and updates current position.\r\n */\r\n save(state: any) {\r\n if (this.position >= this.maxLength) {\r\n this.truncate(this.stack, this.maxLength);\r\n }\r\n this.position = Math.min(this.position, this.stack.length - 1);\r\n\r\n this.stack = this.stack.slice(0, this.position + 1);\r\n\r\n const index = this.blocks.getCurrentBlockIndex();\r\n const blockCount = this.blocks.getBlocksCount();\r\n let indexInState = index;\r\n\r\n if (!state[index]) indexInState -= blockCount - state.length;\r\n const caretIndex =\r\n state[indexInState] && (\r\n state[indexInState].type === \"paragraph\" ||\r\n state[indexInState].type === \"header\")\r\n ? this.getCaretIndex(index)\r\n : null;\r\n this.stack.push({ index: indexInState, state, caretIndex });\r\n this.position += 1;\r\n this.onUpdate();\r\n }\r\n\r\n /**\r\n * Gets the caret position.\r\n * @param {Number} index is the block index\r\n * @returns The caret position\r\n */\r\n getCaretIndex(index: number) {\r\n const blocks = this.holder.getElementsByClassName(\"ce-block__content\");\r\n const caretBlock = new VanillaCaret(blocks[index].firstChild);\r\n\r\n return caretBlock.getPos();\r\n }\r\n\r\n /**\r\n * Inserts a block deleted previously\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Array} compState is the state to compare and know the deleted block.\r\n * @param {Number} index is the block index in state.\r\n */\r\n insertDeletedBlock(state: any, compState: any, index: number) {\r\n for (let i = 0; i < state.length; i += 1) {\r\n if (!compState[i] || state[i].id !== compState[i].id) {\r\n this.blocks.insert(state[i].type, state[i].data, {}, i, true);\r\n this.caret.setToBlock(index, \"end\");\r\n break;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Returns true if a block was dropped previously\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Array} compState is the state to compare and know the dropped block.\r\n * @returns {Boolean} true if the block was dropped\r\n */\r\n blockWasDropped(state: any, compState: any) {\r\n if (state.length === compState.length) {\r\n return state.some((block: any, i: number) => block.id !== compState[i].id);\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Returns true if the block has to be deleted because it was skipped previously.\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Array} compState is the state to compare if there was a deleted block.\r\n * @returns {Boolean} true if a block was inserted previously.\r\n */\r\n blockWasSkipped(state: any, compState: any) {\r\n return state.length !== compState.length;\r\n }\r\n\r\n /**\r\n * Returns true if the content in a block without the focus was modified.\r\n * @param {Number} index is the block index in state.\r\n * @param {Number} compIndex is the index to compare and know if the block was inserted previously\r\n * @returns true if the content in a block without the focus was modified.\r\n */\r\n contentChangedInNoFocusBlock(index: number, compIndex: number) {\r\n return index !== compIndex;\r\n }\r\n\r\n /**\r\n * Returns true if a block was deleted previously.\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Array} compState is the state to compare and know if a block was deleted.\r\n * @returns {Boolean} true if a block was deleted previously.\r\n */\r\n blockWasDeleted(state: any, compState: any) {\r\n return state.length > compState.length;\r\n }\r\n\r\n /**\r\n * Returns true if the content was copied.\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Array} compState is the state to compare and know if the content was copied.\r\n * @param {Number} index is the block index in state.\r\n * @returns {Boolean} true if a block was deleted previously.\r\n */\r\n contentWasCopied(state: any, compState: any, index: number) {\r\n return Object.keys(state[index].data).length === 0\r\n && JSON.stringify(compState[index + 1]) !== JSON.stringify(state[index + 1]);\r\n }\r\n\r\n /**\r\n * Decreases the current position and update the respective block in the editor.\r\n */\r\n async undo() {\r\n if (this.canUndo()) {\r\n const { index: nextIndex, state: nextState } = this.stack[this.position];\r\n\r\n this.position -= 1;\r\n this.shouldSaveHistory = false;\r\n let { index } = this.stack[this.position];\r\n const { state, caretIndex } = this.stack[this.position];\r\n\r\n this.onUpdate();\r\n const blockCount = this.blocks.getBlocksCount();\r\n\r\n if (!state[index]) {\r\n index -= 1;\r\n this.stack[this.position].index = index;\r\n }\r\n\r\n if (this.blockWasDeleted(state, nextState)) {\r\n this.insertDeletedBlock(state, nextState, index);\r\n } else if (this.contentWasCopied(state, nextState, index)) {\r\n await this.blocks.render({ blocks: state });\r\n this.caret.setToBlock(index, 'end');\r\n } else if (index < nextIndex && this.blockWasSkipped(state, nextState)) {\r\n await this.blocks.delete(nextIndex);\r\n this.caret.setToBlock(index, \"end\");\r\n } else if (blockCount > state.length) {\r\n await this.blocks.render({ blocks: state });\r\n this.setCaretIndex(index, caretIndex);\r\n } else if (this.blockWasDropped(state, nextState)) {\r\n await this.blocks.render({ blocks: state });\r\n this.caret.setToBlock(index, 'end');\r\n } else if (this.contentChangedInNoFocusBlock(index, nextIndex)) {\r\n const { id } = this.blocks.getBlockByIndex(nextIndex);\r\n\r\n await this.blocks.update(id, state[nextIndex].data);\r\n this.setCaretIndex(index, caretIndex);\r\n }\r\n\r\n const block = this.blocks.getBlockByIndex(index);\r\n if (block) {\r\n await this.blocks.update(block.id, state[index].data);\r\n this.setCaretIndex(index, caretIndex);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Sets the caret position.\r\n * @param {Number} index is the block index\r\n * @param {Number} caretIndex is the caret position\r\n * @param {Array} state is the current state according to this.position.\r\n */\r\n setCaretIndex(index: number, caretIndex: number) {\r\n if (caretIndex && caretIndex !== -1) {\r\n const blocks = this.holder.getElementsByClassName(\"ce-block__content\");\r\n const caretBlock = new VanillaCaret(blocks[index].firstChild);\r\n setTimeout(() => caretBlock.setPos(caretIndex), 50);\r\n } else {\r\n this.caret.setToBlock(index, \"end\");\r\n }\r\n }\r\n\r\n /**\r\n * Inserts new block\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Number} index is the block index\r\n */\r\n async insertBlock(state: any, index: number) {\r\n await this.blocks.insert(\r\n state[index].type,\r\n state[index].data,\r\n {},\r\n index,\r\n true,\r\n );\r\n }\r\n\r\n /**\r\n * Inserts a block when is skipped and update the previous one if it changed.\r\n * @param {Array} prevState is the previous state according to this.position.\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Number} index is the block index.\r\n */\r\n async insertSkippedBlocks(prevState: any, state: any, index: number) {\r\n for (let i = prevState.length; i < state.length; i += 1) {\r\n this.insertBlock(state, i);\r\n }\r\n\r\n if (JSON.stringify(prevState[index - 1]) !== JSON.stringify(state[index - 1])) {\r\n await this.updateModifiedBlock(state, index);\r\n }\r\n }\r\n\r\n /**\r\n * Updates the passed block or render the state when the content was copied.\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Number} index is the block index.\r\n */\r\n async updateModifiedBlock(state: any, index: number) {\r\n const block = state[index - 1];\r\n if (this.editor!.blocks.getById(block.id)) return this.blocks.update(block.id, block.data);\r\n return this.blocks.render({ blocks: state });\r\n }\r\n\r\n /**\r\n * Increases the current position and update the respective block in the editor.\r\n */\r\n async redo() {\r\n if (this.canRedo()) {\r\n this.position += 1;\r\n this.shouldSaveHistory = false;\r\n const { index, state, caretIndex } = this.stack[(this.position)];\r\n const { index:prevIndex, state: prevState } =\r\n this.stack[this.position - 1];\r\n\r\n if (this.blockWasDeleted(prevState, state)) {\r\n await this.blocks.delete();\r\n this.caret.setToBlock(index, \"end\");\r\n } else if (this.blockWasSkipped(state, prevState)) {\r\n await this.insertSkippedBlocks(prevState, state, index);\r\n this.caret.setToBlock(index, 'end');\r\n } else if (this.blockWasDropped(state, prevState) && this.position !== 1) {\r\n await this.blocks.render({ blocks: state });\r\n this.caret.setToBlock(index, \"end\");\r\n }\r\n\r\n this.onUpdate();\r\n const block = this.blocks.getBlockByIndex(index);\r\n if (block) {\r\n await this.blocks.update(block.id, state[index].data);\r\n this.setCaretIndex(index, caretIndex);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Checks if the history stack can perform an undo action.\r\n *\r\n * @returns {Boolean}\r\n */\r\n canUndo() {\r\n return !this.readOnly && this.position > 0;\r\n }\r\n\r\n /**\r\n * Checks if the history stack can perform a redo action.\r\n *\r\n * @returns {Boolean}\r\n */\r\n canRedo() {\r\n return !this.readOnly && this.position < this.count();\r\n }\r\n\r\n /**\r\n * Returns the number of changes recorded in the history stack.\r\n *\r\n * @returns {Number}\r\n */\r\n count() {\r\n return this.stack.length - 1; // -1 because of initial item\r\n }\r\n\r\n /**\r\n * Parses the keys passed in the shortcut property to accept CMD,ALT and SHIFT\r\n *\r\n * @param {Array} keys are the keys passed in shortcuts in config\r\n * @returns {Array}\r\n */\r\n\r\n parseKeys(keys: string[]) {\r\n const specialKeys: any = {\r\n CMD: /(Mac)/i.test(navigator.platform) ? \"metaKey\" : \"ctrlKey\",\r\n ALT: \"altKey\",\r\n SHIFT: \"shiftKey\",\r\n };\r\n const parsedKeys = keys.slice(0, -1).map((key) => specialKeys[key]);\r\n\r\n const letterKey =\r\n parsedKeys.includes(\"shiftKey\") && keys.length === 2\r\n ? keys[keys.length - 1].toUpperCase()\r\n : keys[keys.length - 1].toLowerCase();\r\n\r\n parsedKeys.push(letterKey);\r\n return parsedKeys;\r\n }\r\n\r\n /**\r\n * Sets events listeners to allow keyboard actions support\r\n */\r\n\r\n setEventListeners() {\r\n const { holder } = this;\r\n const { shortcuts } = this.config;\r\n const { undo, redo } = shortcuts;\r\n const keysUndo = undo.map((undoShortcut: string) => undoShortcut.replace(/ /g, \"\").split(\"+\"));\r\n const keysRedo = redo.map((redoShortcut: string) => redoShortcut.replace(/ /g, \"\").split(\"+\"));\r\n\r\n const keysUndoParsed = keysUndo.map((keys: string[]) => this.parseKeys(keys));\r\n const keysRedoParsed = keysRedo.map((keys: string[]) => this.parseKeys(keys));\r\n\r\n const twoKeysPressed = (e: any, keys: any) => {\r\n return keys.length === 2 && e[keys[0]] && (e.key.toLowerCase() === keys[1]);\r\n }\r\n const threeKeysPressed = (e: any, keys: any) => {\r\n return keys.length === 3 && e[keys[0]] && e[keys[1]] && (e.key.toLowerCase() === keys[2]);\r\n }\r\n const verifyListTwoKeysPressed = (e: KeyboardEvent, keysList:string[]) =>\r\n keysList.reduce((result, keys:string) => result || twoKeysPressed(e, keys), false);\r\n const verifyListThreeKeysPressed = (e: KeyboardEvent, keysList:string[]) =>\r\n keysList.reduce((result, keys) => result || threeKeysPressed(e, keys), false);\r\n\r\n const pressedKeys = (e: KeyboardEvent, keys: string[], compKeys: string[]) => {\r\n if (verifyListTwoKeysPressed(e, keys) && !verifyListThreeKeysPressed(e, compKeys)) {\r\n return true;\r\n }\r\n if (verifyListThreeKeysPressed(e, keys)) {\r\n return true;\r\n }\r\n return false;\r\n };\r\n\r\n const handleUndo = (e: KeyboardEvent) => {\r\n if (pressedKeys(e, keysUndoParsed, keysRedoParsed)) {\r\n e.preventDefault();\r\n this.undo();\r\n }\r\n };\r\n\r\n const handleRedo = (e: KeyboardEvent) => {\r\n if (pressedKeys(e, keysRedoParsed, keysUndoParsed)) {\r\n e.preventDefault();\r\n this.redo();\r\n }\r\n };\r\n\r\n const handleDestroy = () => {\r\n holder.removeEventListener(\"keydown\", handleUndo);\r\n holder.removeEventListener(\"keydown\", handleRedo);\r\n };\r\n\r\n holder.addEventListener(\"keydown\", handleUndo);\r\n holder.addEventListener(\"keydown\", handleRedo);\r\n holder.addEventListener(\"destroy\", handleDestroy);\r\n }\r\n}\r\n","/**\r\n * Alert block for the Editor.js.\r\n *\r\n * @author Vishal Telangre\r\n * @license MIT\r\n */\r\n\r\n/**\r\n * Build styles\r\n */\r\n\r\nimport type { API,BlockTool,BlockToolConstructorOptions } from \"@ebl-vue/editorjs/types\";\r\nimport './index.css';\r\nimport type { HTMLPasteEvent } from '@ebl-vue/editorjs';\r\nimport { IconToolboxAlert as ToolboxIcon,IconAlignLeft as AlignLeftIcon,IconAlignCenter as AlignCenterIcon,IconAlignRight as AlignRightIcon } from \"../../icons\";\r\n\r\n\r\n/**\r\n * @class Alert\r\n * @classdesc Alert Tool for Editor.js\r\n * @property {AlertData} data - Alert Tool`s input and output data\r\n * @property {object} api - Editor.js API instance\r\n *\r\n * @typedef {object} AlertData\r\n * @description Alert Tool`s input and output data\r\n * @property {string} type - Alert type\r\n * @property {string} alignType - Alert align type\r\n * @property {string} message - Alert message\r\n *\r\n * @typedef {object} AlertConfig\r\n * @description Alert Tool`s initial configuration\r\n * @property {string} defaultType - default Alert type\r\n * @property {string} defaultAlignType - default align Alert type\r\n * @property {string} messagePlaceholder - placeholder to show in Alert`s message input\r\n */\r\nexport default class Alert implements BlockTool{\r\n /**\r\n * Get Toolbox settings\r\n *\r\n * @public\r\n * @returns {string}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: ToolboxIcon,\r\n title: 'Alert',\r\n };\r\n }\r\n\r\n /**\r\n * Allow to press Enter inside the Alert block\r\n * @public\r\n * @returns {boolean}\r\n */\r\n static get enableLineBreaks() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Default Alert type\r\n *\r\n * @public\r\n * @returns {string}\r\n */\r\n static get DEFAULT_TYPE() {\r\n return 'info';\r\n }\r\n\r\n /**\r\n * Default Alert align type\r\n *\r\n * @public\r\n * @returns {string}\r\n */\r\n static get DEFAULT_ALIGN_TYPE() {\r\n return 'left';\r\n }\r\n\r\n /**\r\n * Default placeholder for Alert message\r\n *\r\n * @public\r\n * @returns {string}\r\n */\r\n static get DEFAULT_MESSAGE_PLACEHOLDER() {\r\n return 'Type here...';\r\n }\r\n\r\n /**\r\n * Supported Alert types\r\n *\r\n * @public\r\n * @returns {array}\r\n */\r\n static get ALERT_TYPES() {\r\n return [\r\n 'primary',\r\n 'secondary',\r\n 'info',\r\n 'success',\r\n 'warning',\r\n 'danger',\r\n 'light',\r\n 'dark',\r\n ];\r\n }\r\n\r\n /**\r\n * Supported Align types\r\n *\r\n * @public\r\n * @returns {array}\r\n */\r\n static get ALIGN_TYPES() {\r\n return ['left', 'center', 'right'];\r\n }\r\n\r\n /**\r\n * Alert Tool`s styles\r\n *\r\n * @returns {Object}\r\n */\r\n get CSS() {\r\n return {\r\n wrapper: 'cdx-alert',\r\n wrapperForType: (type:string) => `cdx-alert-${type}`,\r\n wrapperForAlignType: (alignType:string) => `cdx-alert-align-${alignType}`,\r\n message: 'cdx-alert__message',\r\n };\r\n }\r\n private alertTypes: string[];\r\n private defaultType: string;\r\n private defaultAlign: string;\r\n private messagePlaceholder: string;\r\n private data: any;\r\n private api: API;\r\n private container: any;\r\n private readOnly: boolean;\r\n\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {AlertData} data — previously saved data\r\n * @param {AlertConfig} config — user config for Tool\r\n * @param {Object} api - Editor.js API\r\n * @param {boolean} readOnly - read only mode flag\r\n */\r\n constructor({ data, config, api, readOnly }:BlockToolConstructorOptions) {\r\n this.api = api;\r\n\r\n this.alertTypes = config.alertTypes || Alert.ALERT_TYPES;\r\n this.defaultType = config.defaultType || Alert.DEFAULT_TYPE;\r\n this.defaultAlign = config.defaultAlign || Alert.DEFAULT_ALIGN_TYPE;\r\n this.messagePlaceholder =\r\n config.messagePlaceholder || Alert.DEFAULT_MESSAGE_PLACEHOLDER;\r\n\r\n this.data = {\r\n type: this.alertTypes.includes(data.type)\r\n ? data.type\r\n : this.defaultType,\r\n align: Alert.ALIGN_TYPES.includes(data.align)\r\n ? data.align\r\n : this.defaultAlign,\r\n message: data.message || '',\r\n };\r\n\r\n this.container = undefined;\r\n\r\n this.readOnly = readOnly;\r\n }\r\n\r\n /**\r\n * Returns true to notify the core that read-only mode is supported\r\n *\r\n * @return {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Create Alert Tool container\r\n *\r\n * @returns {Element}\r\n */\r\n render() {\r\n const containerClasses = [\r\n this.CSS.wrapper,\r\n this.CSS.wrapperForType(this.data.type),\r\n this.CSS.wrapperForAlignType(this.data.align),\r\n ];\r\n\r\n this.container = this._make('div', containerClasses);\r\n\r\n const messageEl = this._make('div', [this.CSS.message], {\r\n contentEditable: !this.readOnly,\r\n innerHTML: this.data.message,\r\n });\r\n\r\n messageEl.dataset.placeholder = this.messagePlaceholder;\r\n\r\n this.container.appendChild(messageEl);\r\n\r\n return this.container;\r\n }\r\n _getSettingIconStyle(type: string) {\r\n let classname = \"\";\r\n switch (type) {\r\n case 'primary':\r\n classname = \"cdx-alert-primary\";\r\n break;\r\n case 'secondary':\r\n classname = \"cdx-alert-secondary\";\r\n break;\r\n case 'info':\r\n classname = \"cdx-alert-info\";\r\n break;\r\n case 'success':\r\n classname = \"cdx-alert-success\";\r\n break;\r\n case 'warning':\r\n classname = \"cdx-alert-warning\";\r\n break;\r\n case 'danger':\r\n classname = \"cdx-alert-danger\";\r\n break;\r\n case 'light':\r\n classname = \"cdx-alert-light\";\r\n break;\r\n case 'dark':\r\n classname = \"cdx-alert-dark\";\r\n break;\r\n }\r\n const iconWrap = this._make('div', ['cdx-alert_setting__icon',classname], {});\r\n return iconWrap;\r\n }\r\n \r\n /**\r\n * Create Block's settings block\r\n *\r\n * @returns {array}\r\n */\r\n renderSettings() {\r\n const wrapper = document.createElement('div');\r\n const alertWrapper = document.createElement('div');\r\n const alignWrapper= document.createElement('div');\r\n alertWrapper.classList.add('cdx-alert_setting__icon_wrapper');\r\n alignWrapper.classList.add('cdx-alert_setting__icon_wrapper');\r\n alignWrapper.classList.add(\"cdx-alert_setting__icon_wrapper_align\");\r\n\r\n this.alertTypes.map((type) => {\r\n let button = this._getSettingIconStyle(type);\r\n button.setAttribute('data-type', type);\r\n\r\n this.api.tooltip.onHover(button, this.api.i18n.t(`alert-${type}`), {\r\n placement: 'top',\r\n }); \r\n button.innerText = \"A\";\r\n alertWrapper.appendChild(button);\r\n return button;\r\n }).forEach((button, index, buttons) => { \r\n const type: string = button.getAttribute('data-type') || \"\";\r\n button.addEventListener('click', () => {\r\n this._changeAlertType(type);\r\n buttons.forEach((el, index) => {\r\n const elType= el.getAttribute('data-type');\r\n el.classList.toggle(\"cdx-alert_setting__icon_active\", elType === this.data.type);\r\n });\r\n });\r\n \r\n\r\n });\r\n\r\n\r\n Alert.ALIGN_TYPES.map((align) => {\r\n let button;\r\n if (align === \"left\") {\r\n button = document.createElement(\"div\");\r\n button.classList.add(\"cdx-alert_setting__icon\");\r\n button.innerHTML = AlignLeftIcon;\r\n }\r\n if (align === \"right\") {\r\n button = document.createElement(\"div\");\r\n button.classList.add(\"cdx-alert_setting__icon\");\r\n button.innerHTML = AlignRightIcon;\r\n\r\n }\r\n if (align === \"center\") {\r\n button = document.createElement(\"div\");\r\n button.classList.add(\"cdx-alert_setting__icon\");\r\n button.innerHTML = AlignCenterIcon;\r\n\r\n\r\n }\r\n\r\n button?.setAttribute(\"data-align\", align);\r\n this.api.tooltip.onHover(button!, this.api.i18n.t(`align-${align}`), {\r\n placement: 'top',\r\n });\r\n alignWrapper.appendChild(button!);\r\n return button;\r\n }).forEach((button, index, buttons) => {\r\n const align: string = button!.getAttribute('data-align') || \"\";\r\n button!.addEventListener('click', () => {\r\n this._changeAlignType(align);\r\n buttons.forEach((el, index) => {\r\n const elAlign = el?.getAttribute('data-align');\r\n el?.classList.toggle(\"cdx-alert_setting__icon_active\", elAlign === this.data.align);\r\n });\r\n });\r\n });\r\n\r\n wrapper.appendChild(alertWrapper);\r\n wrapper.appendChild(alignWrapper);\r\n return wrapper;\r\n }\r\n\r\n /**\r\n * Helper for formatting Alert Type / Align Type\r\n *\r\n * @param {string} type - Alert type or Align type\r\n * @returns {string}\r\n */\r\n _getFormattedName(name: string) {\r\n return this.api.i18n.t(name.charAt(0).toUpperCase() + name.slice(1));\r\n }\r\n\r\n /**\r\n * Helper for changing style of Alert block with the selected Alert type\r\n *\r\n * @param {string} newType - new Alert type to be applied to the block\r\n * @private\r\n */\r\n _changeAlertType(newType: string) {\r\n // Save new type\r\n this.data.type = newType;\r\n\r\n this.alertTypes.forEach((type) => {\r\n const alertClass = this.CSS.wrapperForType(type);\r\n\r\n // Remove the old Alert type class\r\n this.container.classList.remove(alertClass);\r\n\r\n if (newType === type) {\r\n // Add an Alert class for the selected Alert type\r\n this.container.classList.add(alertClass);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Helper for changing align of Alert block with the selected Align type\r\n *\r\n * @param {string} newAlign - new align type to be applied to the block\r\n * @private\r\n */\r\n _changeAlignType(newAlign: string) {\r\n // Save new type\r\n this.data.align = newAlign;\r\n\r\n Alert.ALIGN_TYPES.forEach((align) => {\r\n const alignClass = this.CSS.wrapperForAlignType(align);\r\n\r\n // Remove the old Alert type class\r\n this.container.classList.remove(alignClass);\r\n\r\n if (newAlign === align) {\r\n // Add an Alert class for the selected Alert type\r\n this.container.classList.add(alignClass);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Extract Alert data from Alert Tool element\r\n *\r\n * @param {HTMLDivElement} alertElement - element to save\r\n * @returns {AlertData}\r\n */\r\n save(alertElement: HTMLElement) {\r\n const messageEl = alertElement.querySelector(`.${this.CSS.message}`);\r\n\r\n return { ...this.data, message: messageEl?.innerHTML || '' };\r\n }\r\n\r\n /**\r\n * Helper for making Elements with attributes\r\n *\r\n * @param {string} tagName - new Element tag name\r\n * @param {array|string} classNames - list or name of CSS classname(s)\r\n * @param {Object} attributes - any attributes\r\n * @returns {Element}\r\n * @private\r\n */\r\n _make(tagName:string, classNames:string[]|string|null, attributes:Record<string, any> = {}) {\r\n let el = document.createElement(tagName);\r\n\r\n if (Array.isArray(classNames)) {\r\n el.classList.add(...classNames);\r\n } else if (classNames) {\r\n el.classList.add(classNames);\r\n }\r\n\r\n for (let attrName in attributes) {\r\n //el[attrName] = attributes[attrName];\r\n el.setAttribute(attrName, attributes[attrName]);\r\n }\r\n\r\n return el;\r\n }\r\n\r\n /**\r\n * Fill Alert's message with the pasted content\r\n *\r\n * @param {PasteEvent} event - event with pasted content\r\n */\r\n onPaste(event:HTMLPasteEvent) {\r\n const { data } = event.detail;\r\n\r\n this.data = {\r\n type: this.defaultType,\r\n message: data.innerHTML || '',\r\n };\r\n }\r\n\r\n /**\r\n * Allow Alert to be converted to/from other blocks\r\n */\r\n static get conversionConfig() {\r\n return {\r\n // export Alert's message for other blocks\r\n export: (data:any) => data.message,\r\n // fill Alert's message from other block's export string\r\n import: (string:string) => {\r\n return {\r\n message: string,\r\n type: this.DEFAULT_TYPE,\r\n alignType: this.DEFAULT_ALIGN_TYPE,\r\n };\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer config for Alert Tool saved data\r\n * @returns {Object}\r\n */\r\n static get sanitize() {\r\n return {\r\n message: true,\r\n type: false,\r\n alignType: false,\r\n };\r\n }\r\n}\r\n","import type { BlockTune, API, BlockAPI, BlockAddedEvent,ToolConfig } from '@ebl-vue/editorjs/types'\r\n\r\nimport type { MenuConfig } from '@ebl-vue/editorjs/types/tools'\r\nimport { IconIndentLeft,IconIndentRight } from '../../icons';\r\n\r\nimport './index.css'\r\n\r\n\r\n\r\ninterface ConstructorArgs {\r\n data: IndentData;\r\n config?: ToolConfig;\r\n api: API;\r\n block?: any;\r\n}\r\nexport type TextDirection = 'ltr' | \"rtl\"\r\n\r\nexport type IndentTuneConfig = Partial<IndentTuneConfigOptions>\r\nexport type IndentTuneConfigOptions = Record<'indentSize' | 'maxIndent' | 'minIndent', number> & {\r\n /**\r\n * Specify the editorjs version so that the styles will match your version\r\n */\r\n version?: string;\r\n /**\r\n * Enables auto indent if not null or `true`\r\n * Default disabled.\r\n */\r\n autoIndent?: {\r\n /**\r\n * Tunes you want to apply auto indent for.\r\n * Defaults to all.\r\n */\r\n tuneNames?: string[]\r\n } | boolean;\r\n /**\r\n * Apply a highlight to the indent if not null\r\n */\r\n highlightIndent?: {\r\n className?: string,\r\n /**\r\n * Tunes you want to apply highlight for.\r\n * Defaults to all.\r\n */\r\n tuneNames?: string[]\r\n };\r\n orientation: 'horizontal' | 'vertical';\r\n /**\r\n * Example:\r\n * {\r\n * tableTuneName: { min: 2, max:8 },\r\n * imageTuneName: { min:1 }\r\n * }\r\n */\r\n customBlockIndentLimits: Record<string, Partial<Record<'min' | 'max', number>>>;\r\n /**\r\n * Custom keyboard indent handler.\r\n * Return 'indent' or 'unindent' if you want to change the current indentation.\r\n * Return 'undefined' or pass 'false' instead of a function to disable the shortcut entirely\r\n * Return 'default' for default handling\r\n */\r\n handleShortcut?: ((e: KeyboardEvent, blockId: string) => 'indent' | 'unindent' | \"default\" | undefined) | undefined | false;\r\n /**\r\n * `ltr` | `rtl`\r\n */\r\n direction: TextDirection;\r\n /**\r\n * Handle dynamic direction change (on each block level)\r\n */\r\n directionChangeHandler: null | ((listener: (blockId: string, direction: TextDirection) => void) => void);\r\n} & (\r\n | {\r\n tuneName: string\r\n multiblock: true\r\n }\r\n | {\r\n tuneName: null\r\n multiblock: false\r\n }\r\n )\r\nconst warnings = { orientation: false };\r\nexport type IndentData = { indentLevel: number }\r\nexport default class IndentTune implements BlockTune {\r\n public static get isTune() {\r\n return true\r\n }\r\n public static DATA_WRAPPER_NAME = 'data-block-indent-wrapper'\r\n public static DATA_FOCUSED = 'data-focused'\r\n public static DATA_INDENT_LEVEL = \"data-indent-level\"\r\n private api: API\r\n private block: BlockAPI | undefined\r\n private config: IndentTuneConfigOptions\r\n public data: IndentData\r\n private wrapper: HTMLElement = document.createElement('div')\r\n private DEFAULT_INDENT_KEY = 'Tab' as const;\r\n constructor({ api, data, config, block, ...other }: ConstructorArgs) {\r\n this.api = api\r\n this.block = block\r\n\r\n const defaultConfig: IndentTuneConfigOptions = {\r\n indentSize: 24,\r\n maxIndent: 8,\r\n minIndent: 0,\r\n multiblock: false,\r\n autoIndent: false,\r\n tuneName: null,\r\n orientation: 'horizontal',\r\n customBlockIndentLimits: {},\r\n handleShortcut: undefined,\r\n direction: \"ltr\",\r\n directionChangeHandler: null,\r\n version: \"2.30\",\r\n }\r\n if (!config && \"settings\" in other)\r\n // for older versions\r\n config = other.settings as any ?? {}\r\n this.config = {\r\n ...defaultConfig,\r\n ...(config ?? {}),\r\n }\r\n\r\n this.changeConfigBasedOnVersionIfNeeded();\r\n\r\n if (this.config?.directionChangeHandler) {\r\n this.config.directionChangeHandler(this.alignmentChangeListener.bind(this));\r\n }\r\n\r\n const defaultIndentLevel = this.config.customBlockIndentLimits[this.block?.name ?? '']?.min ?? this.config.minIndent\r\n this.data = {\r\n //@ts-ignore\r\n indentLevel: defaultIndentLevel,\r\n ...(data ?? {}),\r\n }\r\n\r\n if (this.config.multiblock && !this.config.tuneName)\r\n console.error(\"IndentTune config 'tuneName' was not provided, this is required for multiblock option to work.\")\r\n\r\n window.addEventListener('resize', (e) => this.onResize.call(this, e))\r\n\r\n // this is called after the indent tune constructor is created\r\n this.api.events.on(\"block changed\", ({ event }: { event: BlockAddedEvent }) => {\r\n const targetId = event.detail.target.id;\r\n const currentBlockId = this.block?.id;\r\n const isSameTarget = currentBlockId === targetId\r\n if (!isSameTarget) return;\r\n\r\n if (!this.shouldApplyAutoIndent) return\r\n queueMicrotask(() => this.autoIndentBlock())\r\n })\r\n }\r\n\r\n\r\n public prepare?(): void | Promise<void> {\r\n\r\n }\r\n public reset?(): void | Promise<void> {\r\n\r\n }\r\n\r\n\r\n public render(): HTMLElement | MenuConfig {\r\n //Disable items after they are rendered synchronously\r\n const disableItemOnRender = () => {\r\n if (this.data.indentLevel == this.maxIndent) {\r\n const element = this.getTuneButton('indent');\r\n element?.classList.add(this.CSS.disabledItem)\r\n if (!element) return true;\r\n\r\n }\r\n if (this.data.indentLevel == this.minIndent) {\r\n const element = this.getTuneButton('unindent');\r\n element?.classList.add(this.CSS.disabledItem)\r\n if (!element) return true;\r\n }\r\n }\r\n queueMicrotask(() => {\r\n const shouldUseMacroTask = disableItemOnRender();\r\n if (shouldUseMacroTask)\r\n setTimeout(disableItemOnRender, 300)\r\n })\r\n\r\n\r\n if (this.config.orientation === 'vertical') {\r\n const leftElementName = `${this.TuneNames.indentLeft}-${this.block?.id}`;\r\n const rightElementName = `${this.TuneNames.indentRight}-${this.block?.id}`\r\n return [\r\n {\r\n title: this.rightText,\r\n hint: {\r\n title: this.api.i18n.t(this.rightText),\r\n },\r\n onActivate: (item, event) => {\r\n this.handleIndentRight();\r\n // override editorjs internal title copy\r\n //@ts-ignore\r\n item.title = this.rightText;\r\n },\r\n icon: IconIndentRight,\r\n name: rightElementName,\r\n },\r\n {\r\n title: this.leftText,\r\n hint: {\r\n title: this.api.i18n.t(this.leftText),\r\n },\r\n onActivate: (item, event) => {\r\n this.handleIndentLeft()\r\n //@ts-ignore\r\n item.title = this.leftText;\r\n },\r\n icon: IconIndentLeft,\r\n name: leftElementName,\r\n },\r\n ]\r\n }\r\n\r\n const html = /*html*/ `\r\n\t\t\t<div class=\"${this.CSS.popoverItem} ${this.CSS.customPopoverItem}\" data-item-name='indent' version=${this.config.version}>\r\n\t\t\t\t<button type=\"button\" class=\"${this.CSS.popoverItemIcon}\" data-${this.TuneNames.indentLeft}>${IconIndentLeft}</button>\r\n\t\t\t\t<span class=\"${this.CSS.popoverItemTitle}\">${this.api.sanitizer.clean(this.api.i18n.t('Indent'), {})}</span>\r\n\t\t\t\t<button type=\"button\" class=\"${this.CSS.popoverItemIcon}\" data-${this.TuneNames.indentRight} style=\"margin-left:10px;\">${IconIndentRight}</button>\r\n\t\t\t</div>\r\n\t\t`\r\n\r\n const item = this.createElementFromTemplate(html);\r\n const rightBtn = item.querySelector(`[data-${this.TuneNames.indentRight}]`);\r\n const leftBtn = item.querySelector(`[data-${this.TuneNames.indentLeft}]`);\r\n if (rightBtn) {\r\n rightBtn.addEventListener('click', () => this.handleIndentRight());\r\n this.api.tooltip.onHover(rightBtn as HTMLElement, this.api.i18n.t('Indent right'), {\r\n placement: 'top',\r\n });\r\n }\r\n if (leftBtn) {\r\n leftBtn.addEventListener('click', () => this.handleIndentLeft());\r\n this.api.tooltip.onHover(leftBtn as HTMLElement, this.api.i18n.t('Indent left'), {\r\n placement: 'top',\r\n });\r\n }\r\n return item\r\n }\r\n\r\n public wrap(pluginsContent: HTMLElement): HTMLElement {\r\n this.wrapper.appendChild(pluginsContent)\r\n this.wrapper.setAttribute(IndentTune.DATA_WRAPPER_NAME, '')\r\n\r\n let applyBlockHighlight = Boolean(this.config.highlightIndent)\r\n if (this.config.highlightIndent?.tuneNames) {\r\n const shouldIgnoreThisBlock = !this.config.highlightIndent.tuneNames.includes(this.block?.name ?? \"\")\r\n if (shouldIgnoreThisBlock)\r\n applyBlockHighlight = false\r\n }\r\n if (applyBlockHighlight) {\r\n const highlightEl = this.createElementFromTemplate(/*html*/`\r\n <div class=\"${this.config.highlightIndent?.className ?? \"\"} ${this.CSS.highlightIndent}\">\r\n </div>\r\n `);\r\n const contentEl = pluginsContent.classList.contains(this.EditorCSS.content) ? pluginsContent : pluginsContent.querySelector(`.${this.EditorCSS.content}`)\r\n contentEl?.appendChild(highlightEl);\r\n }\r\n\r\n this.applyStylesToWrapper(this.wrapper, this.data.indentLevel)\r\n\r\n // this.wrapper.addEventListener(\"keypress\", this.handlePropagationForKeyEvent.bind(this), { capture: true })\r\n // this.wrapper.addEventListener(\"keyup\", this.handlePropagationForKeyEvent.bind(this), { capture: true })\r\n this.wrapper.addEventListener('keydown', (...args) => this.onKeyDown.apply(this, args), { capture: true })\r\n this.wrapper.addEventListener(\"focus\", (e) => this.onFocus.call(this, e), { capture: true });\r\n this.wrapper.addEventListener(\"blur\", (e) => this.onBlur.call(this, e), { capture: true });\r\n\r\n return this.wrapper\r\n }\r\n\r\n public save() {\r\n return this.data\r\n }\r\n\r\n private get CSS() {\r\n return {\r\n customPopoverItem: 'ce-popover-indent-item',\r\n popoverItem: 'ce-popover-item',\r\n popoverItemIcon: 'ce-popover-item__icon',\r\n popoverItemTitle: 'ce-popover-item__title',\r\n disabledItem: 'ce-popover-item--disabled',\r\n highlightIndent: \"ce-highlight-indent\",\r\n }\r\n }\r\n private get EditorCSS() {\r\n return {\r\n block: \"ce-block\",\r\n content: \"ce-block__content\",\r\n redactor: \"codex-editor__redactor\",\r\n }\r\n }\r\n\r\n private get TuneNames() {\r\n return {\r\n indentLeft: 'tune-indent-left',\r\n indentRight: 'tune-indent-right',\r\n }\r\n }\r\n\r\n private get customInterval() {\r\n return this.config.customBlockIndentLimits[this.block?.name ?? ''] ?? {}\r\n }\r\n\r\n private get maxIndent() {\r\n return this.customInterval.max ?? this.config.maxIndent\r\n }\r\n\r\n private get minIndent() {\r\n return this.customInterval.min ?? this.config.minIndent\r\n }\r\n\r\n private get isDirectionInverted() {\r\n return this.config.direction !== 'ltr'; // also ignore invalid directions\r\n }\r\n\r\n private get rightText() {\r\n return this.api.i18n.t(this.isDirectionInverted ? 'Un Indent' : 'Indent')\r\n }\r\n\r\n private get leftText() {\r\n return this.api.i18n.t(this.isDirectionInverted ? 'Indent' : 'Un Indent')\r\n }\r\n\r\n private get shouldApplyAutoIndent(): boolean {\r\n if (!this.config.autoIndent) return false\r\n if (typeof this.config.autoIndent === 'boolean') return this.config.autoIndent;\r\n\r\n // the index is still on the previous block\r\n const previousBlockIndex = this.api.blocks.getCurrentBlockIndex()\r\n // const previousBlockIndex = currentBlockIndex// - 1;\r\n if (previousBlockIndex < 0) return false;\r\n\r\n const previousBlock = this.api.blocks.getBlockByIndex(previousBlockIndex)\r\n if (!previousBlock) return false;\r\n\r\n const previousBlockName = previousBlock.name;\r\n return !this.config.autoIndent.tuneNames?.length || this.config.autoIndent.tuneNames.includes(previousBlockName)\r\n }\r\n\r\n private handlePropagationForKeyEvent(e: KeyboardEvent): { isIndent: boolean } | null {\r\n if (!this.block?.id) return null;\r\n // omit key shortcut entirely\r\n if (this.config.handleShortcut === false) return null;\r\n\r\n const isDefaultKeyPressed = e.key == this.DEFAULT_INDENT_KEY\r\n const isCustomBehaviourDefined = typeof this.config.handleShortcut === 'function'\r\n\r\n if (!isCustomBehaviourDefined && !isDefaultKeyPressed) return null\r\n\r\n const handledCommand = this.config.handleShortcut?.(e, this.block.id)\r\n const shouldIgnoreKeyPress = !handledCommand && isCustomBehaviourDefined\r\n if (shouldIgnoreKeyPress) return null\r\n\r\n let isIndent: boolean;\r\n switch (handledCommand) {\r\n case 'indent':\r\n isIndent = true;\r\n break\r\n case 'unindent':\r\n isIndent = false;\r\n break;\r\n case 'default':\r\n default:\r\n if (!isDefaultKeyPressed) return null;\r\n isIndent = !e.shiftKey\r\n }\r\n\r\n e.stopPropagation()\r\n e.preventDefault()\r\n\r\n return { isIndent }\r\n }\r\n\r\n private onKeyDown(e: KeyboardEvent) {\r\n if (!this.block?.id) return;\r\n\r\n const handlingResult = this.handlePropagationForKeyEvent(e)\r\n if (!handlingResult) return;\r\n const { isIndent } = handlingResult\r\n\r\n //this might be still open\r\n this.api.inlineToolbar.close()\r\n const selectedBlocks = this.getGlobalSelectedBlocks()\r\n const isSingleLineBlock = !this.config.multiblock || selectedBlocks.length < 2\r\n if (isSingleLineBlock) {\r\n if (isIndent) this.indentBlock()\r\n else this.unIndentBlock()\r\n this.block.dispatchChange?.()\r\n return\r\n }\r\n\r\n if (!Boolean(this.config.tuneName)) {\r\n console.error(`'tuneName' is empty.`)\r\n return\r\n }\r\n\r\n selectedBlocks.forEach(async (b) => {\r\n //get block indent level\r\n const savedData = await b.save()\r\n if (!savedData) return\r\n\r\n if (!('tunes' in savedData) || typeof savedData.tunes !== 'object' || !savedData.tunes) {\r\n console.error('Multiblock indenting is not supported for this editor version. ')\r\n return\r\n }\r\n\r\n //this somehow SAVES fine\r\n const tune = (savedData.tunes as Record<string, IndentData>)[this.config.tuneName ?? ''] as IndentData | undefined\r\n if (!tune) {\r\n console.error(`'tuneName' is invalid, no tune was found for block ${b.name}`)\r\n return\r\n }\r\n if (isIndent) tune.indentLevel = Math.min(this.config.maxIndent, (tune.indentLevel ?? 0) + 1)\r\n else tune.indentLevel = Math.max(0, (tune.indentLevel ?? 0) - 1)\r\n b.dispatchChange?.()\r\n\r\n //apply visual feedback manually, since we can't make the tune update on other blocks\r\n const blockWrapper = this.getWrapperBlockById(b.id)\r\n if (blockWrapper instanceof HTMLElement) {\r\n this.applyStylesToWrapper(blockWrapper, tune.indentLevel)\r\n }\r\n })\r\n }\r\n\r\n private handleIndentLeft() {\r\n if (this.isDirectionInverted)\r\n this.indentBlock();\r\n else\r\n this.unIndentBlock();\r\n this.block?.dispatchChange?.()\r\n }\r\n\r\n private handleIndentRight() {\r\n if (this.isDirectionInverted)\r\n this.unIndentBlock();\r\n else\r\n this.indentBlock();\r\n this.block?.dispatchChange?.()\r\n }\r\n\r\n private indentBlock() {\r\n if (!this.wrapper) return\r\n this.data.indentLevel = Math.min(this.data.indentLevel + 1, this.maxIndent)\r\n\r\n this.applyStylesToWrapper(this.wrapper, this.data.indentLevel)\r\n\r\n this.toggleDisableStateForButtons()\r\n }\r\n\r\n private unIndentBlock() {\r\n if (!this.wrapper) return\r\n this.data.indentLevel = Math.max(this.data.indentLevel - 1, this.minIndent)\r\n\r\n this.applyStylesToWrapper(this.wrapper, this.data.indentLevel)\r\n\r\n this.toggleDisableStateForButtons()\r\n }\r\n\r\n private autoIndentBlock() {\r\n const currentBlockIndex = this.api.blocks.getBlockIndex(this.block!.id)\r\n const previousBlock = this.api.blocks.getBlockByIndex(currentBlockIndex - 1)\r\n\r\n if (!previousBlock) return\r\n\r\n const previousBlockIndentLevelAttribute = previousBlock.holder?.querySelector(`[${IndentTune.DATA_WRAPPER_NAME}]`)\r\n ?.getAttribute(IndentTune.DATA_INDENT_LEVEL);\r\n\r\n const previousBlockIndentLevel = Number(\r\n previousBlockIndentLevelAttribute ?? 0,\r\n )\r\n\r\n const currentBlockIndentLevel = Math.min(Math.max(previousBlockIndentLevel, this.minIndent), this.maxIndent)\r\n\r\n this.data.indentLevel = currentBlockIndentLevel\r\n\r\n this.applyStylesToWrapper(this.wrapper, this.data.indentLevel)\r\n }\r\n\r\n private toggleDisableStateForButtons() {\r\n if (this.data.indentLevel === this.minIndent)\r\n this.getTuneButton('unindent')?.classList.add(this.CSS.disabledItem)\r\n else\r\n this.getTuneButton('unindent')?.classList.remove(this.CSS.disabledItem)\r\n\r\n if (this.data.indentLevel === this.maxIndent)\r\n this.getTuneButton('indent')?.classList.add(this.CSS.disabledItem)\r\n else\r\n this.getTuneButton('indent')?.classList.remove(this.CSS.disabledItem)\r\n }\r\n\r\n private getTuneButton(indentType: 'indent' | 'unindent') {\r\n let indentName: 'indentLeft' | \"indentRight\" = indentType === 'indent' ? \"indentRight\" : \"indentLeft\";\r\n if (this.isDirectionInverted)\r\n indentName = indentType == 'indent' ? \"indentLeft\" : \"indentRight\";\r\n\r\n return this.config.orientation === 'vertical'\r\n ? this.getTuneByName(`${this.TuneNames[indentName]}-${this.block?.id}`)\r\n : document.querySelector(`.${this.CSS.popoverItemIcon}[data-${this.TuneNames[indentName]}]`)\r\n }\r\n\r\n private getTuneByName(name: string) {\r\n return document.querySelector(`.${this.CSS.popoverItem}[data-item-name=\"${name}\"]`)\r\n }\r\n\r\n private getTuneTitleByName(name: string) {\r\n return this.getTuneByName(name)?.querySelector(`.${this.CSS.popoverItemTitle}`)\r\n }\r\n\r\n private applyStylesToWrapper(givenWrapper: HTMLElement, indentLevel: number = parseInt(givenWrapper.getAttribute(IndentTune.DATA_INDENT_LEVEL) || \"0\")) {\r\n const indentValue = indentLevel * this.config.indentSize;\r\n givenWrapper.setAttribute(IndentTune.DATA_INDENT_LEVEL, indentLevel.toString());\r\n\r\n const contentElement = givenWrapper.querySelector(`.${this.EditorCSS.content}`);\r\n const blockElement = this.getBlockForWrapper(givenWrapper) || document.querySelector(`.${this.EditorCSS.redactor}`);\r\n if (!(contentElement instanceof HTMLElement) || !blockElement) return;\r\n\r\n const blockWidth = blockElement.getBoundingClientRect().width;\r\n if (blockWidth === 0) //block is not in DOM yet/redactor is hidden, depends on editorjs version\r\n {\r\n queueMicrotask(() => this.applyStylesToWrapper.bind(this)(givenWrapper, indentLevel))\r\n return\r\n }\r\n const normalContentWidth = this.maxWidthForContent(givenWrapper);\r\n\r\n // until margin inline == 0;\r\n const maxApplyableIndent = (blockWidth - normalContentWidth) / 2\r\n\r\n const indentToApply = Math.max(0, Math.min(maxApplyableIndent, indentValue));\r\n //have to double the value because content inside has margin inline;\r\n const indentValuePixels = `${indentToApply * 2}px`;\r\n const indentValuePixelsForHighlight = `${indentToApply}px`;\r\n\r\n // because the direction has been changed\r\n // const omitTransitionTemporarily = givenWrapper.style[this.isDirectionInverted ? 'paddingLeft' : \"paddingRight\"] === \"0px\"\r\n // if (omitTransitionTemporarily) this.omitTransitionTemporarily(givenWrapper)\r\n\r\n if (this.isDirectionInverted) {\r\n givenWrapper.style.paddingLeft = '0px';\r\n givenWrapper.style.paddingRight = indentValuePixels;\r\n } else {\r\n givenWrapper.style.paddingLeft = indentValuePixels;\r\n givenWrapper.style.paddingRight = \"0px\";\r\n }\r\n\r\n const highlightElement = givenWrapper.querySelector(`.${this.CSS.highlightIndent}`)\r\n if (!(highlightElement instanceof HTMLElement)) return;\r\n\r\n // if (omitTransitionTemporarily) this.omitTransitionTemporarily(highlightElement)\r\n\r\n if (this.isDirectionInverted) {\r\n highlightElement.style.width = indentValuePixelsForHighlight;\r\n highlightElement.style.left = \"100%\";\r\n highlightElement.style.right = '';\r\n }\r\n else {\r\n highlightElement.style.width = indentValuePixelsForHighlight;\r\n highlightElement.style.left = \"\";\r\n highlightElement.style.right = '100%';\r\n }\r\n }\r\n\r\n private onFocus(e: FocusEvent) {\r\n if (!(e.target instanceof HTMLElement)) return;\r\n const isInsideCurrentBlock = this.wrapper.contains(e.target);\r\n if (!isInsideCurrentBlock) return;\r\n this.wrapper.setAttribute(IndentTune.DATA_FOCUSED, '');\r\n }\r\n\r\n private onBlur(e: FocusEvent) {\r\n if (!(e.target instanceof HTMLElement)) return;\r\n const isInsideCurrentBlock = this.wrapper.contains(e.target);\r\n if (!isInsideCurrentBlock) return;\r\n this.wrapper.removeAttribute(IndentTune.DATA_FOCUSED);\r\n }\r\n\r\n private lastResizeTimeout: null | NodeJS.Timeout = null;\r\n private onResize(e: UIEvent) {\r\n const timeoutDelayMs = 500;\r\n if (this.lastResizeTimeout)\r\n clearTimeout(this.lastResizeTimeout)\r\n this.lastResizeTimeout = setTimeout(() => {\r\n const allWrappers = document.querySelectorAll(`[${IndentTune.DATA_WRAPPER_NAME}]`);\r\n allWrappers.forEach((w) => {\r\n if (!(w instanceof HTMLElement)) return;\r\n this.applyStylesToWrapper(w);\r\n });\r\n }, timeoutDelayMs);\r\n }\r\n\r\n private getGlobalSelectedBlocks() {\r\n const crossSelectedBlocks = new Array(this.api.blocks.getBlocksCount())\r\n .fill(0)\r\n .map((_, idx) => this.api.blocks.getBlockByIndex(idx))\r\n .filter((b): b is BlockAPI => !!b?.selected)\r\n return crossSelectedBlocks\r\n }\r\n\r\n private getWrapperBlockById(blockId: string) {\r\n const selector = `.${this.EditorCSS.block}[data-id=\"${blockId}\"] [${IndentTune.DATA_WRAPPER_NAME}]`\r\n return document.querySelector(selector) ??\r\n this.api.blocks.getById(blockId)?.holder.querySelector(`[${IndentTune.DATA_WRAPPER_NAME}]`)\r\n ?? null;\r\n }\r\n\r\n private getBlockForWrapper(wrapper: HTMLElement): HTMLElement | null {\r\n let current = wrapper;\r\n while ((!current.classList.contains(this.EditorCSS.block))) {\r\n if (!current.parentElement || (current instanceof HTMLHtmlElement)) return null;\r\n current = current.parentElement;\r\n }\r\n\r\n return current\r\n }\r\n\r\n private alignmentChangeListener(blockId: string, direction: TextDirection) {\r\n // across all blocks this function is called, so we got to filter out\r\n if (blockId !== this.block?.id) return;\r\n const hasDirectionChanged = direction !== this.config.direction\r\n if (!hasDirectionChanged) return\r\n\r\n this.config.direction = direction;\r\n this.applyStylesToWrapper(this.wrapper, this.data.indentLevel)\r\n this.toggleDisableStateForButtons()\r\n if (this.config.orientation === 'vertical') {\r\n // I have to update the text for the indent options 😪\r\n\r\n const indentRightBtnTitle = this.getTuneTitleByName(`${this.TuneNames.indentRight}-${this.block?.id}`);\r\n if (indentRightBtnTitle) indentRightBtnTitle.textContent = this.rightText\r\n\r\n const indentLeftBtnTitle = this.getTuneTitleByName(`${this.TuneNames.indentLeft}-${this.block?.id}`);\r\n if (indentLeftBtnTitle) indentLeftBtnTitle.textContent = this.leftText\r\n }\r\n }\r\n\r\n private createElementFromTemplate(template: string): HTMLElement {\r\n return new DOMParser().parseFromString(template, 'text/html').body.firstChild as HTMLElement;\r\n }\r\n\r\n // private omitTransitionTemporarily(element: HTMLElement) {\r\n // element.style.transitionDuration = \"0s\";\r\n // (() => {\r\n // element.style.transitionDuration = \"\";\r\n // })\r\n // }\r\n\r\n private changeConfigBasedOnVersionIfNeeded() {\r\n if (!this.config.version) return;\r\n\r\n if (this.config.version < '2.27' && this.config.orientation === 'vertical') {\r\n this.config.orientation = 'horizontal';\r\n\r\n if (!warnings.orientation)\r\n console.warn(\"Current editor version does not support vertical indent tune 'orientation'. View your config input\")\r\n warnings.orientation = true;\r\n }\r\n }\r\n\r\n private cachedMaxWidthForContent: number | null = null;\r\n private maxWidthForContent(elementInsideEditor: HTMLElement): number {\r\n const content = elementInsideEditor.querySelector(`.${this.EditorCSS.content}`);\r\n if ((content instanceof HTMLElement)) {\r\n const { maxWidth } = window.getComputedStyle(content);\r\n if (maxWidth) {\r\n this.cachedMaxWidthForContent = parseInt(maxWidth);\r\n return this.cachedMaxWidthForContent\r\n }\r\n }\r\n\r\n if (this.cachedMaxWidthForContent !== null) return this.cachedMaxWidthForContent\r\n // Get value from stylesheet\r\n // for (let i = 0; i < document.styleSheets.length; i++) {\r\n // const styleSheet = document.styleSheets.item(i);\r\n // if (!styleSheet || !(styleSheet.ownerNode instanceof HTMLStyleElement) || styleSheet.ownerNode.id !== \"editor-js-styles\") continue;\r\n\r\n // for (let j = 0; j < styleSheet.cssRules.length; j++) {\r\n // const rule = styleSheet.cssRules.item(j);\r\n // if (!rule) continue;\r\n // const selector = `.${this.EditorCSS.content}`\r\n // if (!rule.cssText.startsWith(selector + \" {\") && (rule as { selectorText?: string }).selectorText !== selector)\r\n // continue;\r\n // const matches = /max-width: [\\d]+px;/.exec(rule.cssText)\r\n // if (!matches || !matches.length) continue;\r\n\r\n // const maxWidth = parseInt(matches[0].replace(\"max-width:\", ''));\r\n // this.cachedMaxWidthForContent = maxWidth;\r\n // return this.maxWidthForContent;\r\n // }\r\n\r\n // }\r\n // console.warn(\"Cannot detect EditorJs max width for content. Please contact package author\")\r\n this.cachedMaxWidthForContent = 650;\r\n return this.cachedMaxWidthForContent;\r\n }\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\nimport type { API } from '@ebl-vue/editorjs';\r\nimport { IconMarker } from '../../icons';\r\n\r\n/**\r\n * Marker Tool for the Editor.js\r\n *\r\n * Allows to wrap inline fragment and style it somehow.\r\n */\r\nexport default class Marker {\r\n private api: API;\r\n private button: HTMLElement | null;\r\n private tag: string;\r\n private iconClasses: {base: string; active: string};\r\n\r\n static get toolboxIcon() {\r\n return IconMarker;\r\n }\r\n /**\r\n * Class name for term-tag\r\n *\r\n * @type {string}\r\n */\r\n static get CSS() {\r\n return 'cdx-marker';\r\n };\r\n\r\n /**\r\n * @param {{api: object}} - Editor.js API\r\n */\r\n constructor({api}: {api: any}) {\r\n this.api = api;\r\n\r\n /**\r\n * Toolbar Button\r\n *\r\n * @type {HTMLElement|null}\r\n */\r\n this.button = null;\r\n\r\n /**\r\n * Tag represented the term\r\n *\r\n * @type {string}\r\n */\r\n this.tag = 'MARK';\r\n\r\n /**\r\n * CSS classes\r\n */\r\n this.iconClasses = {\r\n base: this.api.styles.inlineToolButton,\r\n active: this.api.styles.inlineToolButtonActive\r\n };\r\n }\r\n\r\n /**\r\n * Specifies Tool as Inline Toolbar Tool\r\n *\r\n * @return {boolean}\r\n */\r\n static get isInline() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Create button element for Toolbar\r\n *\r\n * @return {HTMLElement}\r\n */\r\n render() {\r\n this.button = document.createElement('button');\r\n //this.button.type = 'button';\r\n this.button.setAttribute(\"type\", \"button\");\r\n this.button.classList.add(this.iconClasses.base);\r\n this.button.innerHTML = this.toolboxIcon;\r\n\r\n return this.button;\r\n }\r\n\r\n /**\r\n * Wrap/Unwrap selected fragment\r\n *\r\n * @param {Range} range - selected fragment\r\n */\r\n surround(range:Range) {\r\n if (!range) {\r\n return;\r\n }\r\n\r\n let termWrapper = this.api.selection.findParentTag(this.tag, Marker.CSS);\r\n\r\n /**\r\n * If start or end of selection is in the highlighted block\r\n */\r\n if (termWrapper) {\r\n this.unwrap(termWrapper);\r\n } else {\r\n this.wrap(range);\r\n }\r\n }\r\n\r\n /**\r\n * Wrap selection with term-tag\r\n *\r\n * @param {Range} range - selected fragment\r\n */\r\n wrap(range:Range) {\r\n /**\r\n * Create a wrapper for highlighting\r\n */\r\n let marker = document.createElement(this.tag);\r\n\r\n marker.classList.add(Marker.CSS);\r\n\r\n /**\r\n * SurroundContent throws an error if the Range splits a non-Text node with only one of its boundary points\r\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Range/surroundContents}\r\n *\r\n * // range.surroundContents(span);\r\n */\r\n marker.appendChild(range.extractContents());\r\n range.insertNode(marker);\r\n\r\n /**\r\n * Expand (add) selection to highlighted block\r\n */\r\n this.api.selection.expandToTag(marker);\r\n }\r\n\r\n /**\r\n * Unwrap term-tag\r\n *\r\n * @param {HTMLElement} termWrapper - term wrapper tag\r\n */\r\n unwrap(termWrapper: HTMLElement) {\r\n /**\r\n * Expand selection to all term-tag\r\n */\r\n this.api.selection.expandToTag(termWrapper);\r\n\r\n let sel = window.getSelection();\r\n let range = sel?.getRangeAt(0);\r\n\r\n let unwrappedContent = range?.extractContents();\r\n\r\n /**\r\n * Remove empty term-tag\r\n */\r\n termWrapper?.parentNode?.removeChild(termWrapper);\r\n\r\n /**\r\n * Insert extracted content\r\n */\r\n if (unwrappedContent) {\r\n range?.insertNode(unwrappedContent);\r\n }\r\n /**\r\n * Restore selection\r\n */\r\n sel?.removeAllRanges();\r\n if (range) {\r\n sel?.addRange(range);\r\n }\r\n }\r\n\r\n /**\r\n * Check and change Term's state for current selection\r\n */\r\n checkState() {\r\n const termTag = this.api.selection.findParentTag(this.tag, Marker.CSS);\r\n\r\n this.button?.classList.toggle(this.iconClasses.active, !!termTag);\r\n }\r\n\r\n /**\r\n * Get Tool icon's SVG\r\n * @return {string}\r\n */\r\n get toolboxIcon() {\r\n return IconMarker;\r\n }\r\n\r\n /**\r\n * Sanitizer rule\r\n * @return {{mark: {class: string}}}\r\n */\r\n static get sanitize() {\r\n return {\r\n mark: {\r\n class: Marker.CSS\r\n }\r\n };\r\n }\r\n}\r\n\r\n","import { API } from '@ebl-vue/editorjs';\r\nimport { IconColor } from \"../../icons\";\r\n\r\n\r\nimport './styles.css';\r\n\r\nimport {type InlineToolConstructorOptions} from \"@ebl-vue/editorjs/types/tools/inline-tool\";\r\n\r\n\r\n\r\nexport default class ColorPicker {\r\n\tprivate api: API;\r\n\r\n\ttag = 'SPAN';\r\n\tclass = 'cdx-text-color';\r\n\tdefaultColor = '#2644FF';\r\n\r\n\tlastRange: Range | null = null;\r\n\r\n\tcolors: string[] = [\r\n\t\t'#182a4e',\r\n\t\t'#0055cc',\r\n\t\t'#1f6a83',\r\n\t\t'#206e4e',\r\n\t\t'#e56910',\r\n\t\t'#ae2e24',\r\n\t\t'#5e4db2',\r\n\t\t'#758195',\r\n\t\t'#1e7afd',\r\n\t\t'#2998bd',\r\n\t\t'#23a06b',\r\n\t\t'#fea363',\r\n\t\t'#c9372c',\r\n\t\t'#8270db',\r\n\t];\r\n\tcolumns = 7;\r\n\r\n\tstatic get title() {\r\n\t\treturn 'Color';\r\n\t}\r\n\r\n\tstatic get isInline() {\r\n\t\treturn true;\r\n\t}\r\n\r\n\tconstructor(args:InlineToolConstructorOptions) {\r\n\t\tconst { api, config } = args;\r\n\t\tthis.api = api;\r\n\r\n\t\tif (config.colors) {\r\n\t\t\tthis.colors = config.colors;\r\n\t\t}\r\n\t\tif (config.columns) {\r\n\t\t\tthis.columns = config.columns;\r\n\t\t}\r\n\t}\r\n\r\n\trender() {\r\n\t\tconst button = document.createElement('button');\r\n\r\n\t\tbutton.type = 'button';\r\n\t\tbutton.innerHTML = IconColor;\r\n\t\tbutton.classList.add(this.api.styles.inlineToolButton);\r\n\r\n\t\tbutton.addEventListener('mousedown', (e) => {\r\n\t\t\t// prevent text deselection when clicking the button\r\n\t\t\te.preventDefault();\r\n\t\t});\r\n\r\n\t\treturn button;\r\n\t}\r\n\r\n\tsurround(range: Range | null) {\r\n\t\tthis.lastRange = range;\r\n\t}\r\n\r\n\twrapAndColor(range: Range | null, color: string) {\r\n\t\tif (!range) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst selectedText = range.extractContents();\r\n\t\tconst span = document.createElement(this.tag);\r\n\t\tspan.classList.add(this.class);\r\n\t\tspan.appendChild(selectedText);\r\n\t\tspan.style.color = color;\r\n\t\tspan.innerHTML = span.textContent || '';\r\n\t\trange.insertNode(span);\r\n\r\n\t\tthis.api.selection.expandToTag(span);\r\n\t}\r\n\r\n\trenderActions() {\r\n\t\tconst container = document.createElement('div');\r\n\t\tcontainer.classList.add('editorjs__color-selector-container');\r\n\t\tcontainer.style.gridTemplateColumns = `repeat(${this.columns}, 1fr)`;\r\n\r\n\t\tthis.colors.forEach((colorValue) => {\r\n\t\t\tconst color = document.createElement('div');\r\n\t\t\tcolor.classList.add('editorjs__color-selector__container-item');\r\n\t\t\tcolor.style.backgroundColor = colorValue;\r\n\t\t\tcolor.onclick = () => {\r\n\t\t\t\tthis.wrapAndColor(this.lastRange, colorValue);\r\n\t\t\t};\r\n\t\t\tcontainer.append(color);\r\n\t\t});\r\n\r\n\t\treturn container;\r\n\t}\r\n\r\n\t/**\r\n\t * Sanitizer rules\r\n\t *\r\n\t * @returns {object}\r\n\t */\r\n\tstatic get sanitize(): any {\r\n\t\treturn {\r\n\t\t\tspan: {\r\n\t\t\t\tstyle: {\r\n\t\t\t\t\tcolor: true,\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t};\r\n\t}\r\n}\r\n\r\nexport class ColorPickerWithoutSanitize extends ColorPicker {\r\n\tstatic override get sanitize() {\r\n\t\treturn undefined;\r\n\t}\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\nimport { IconUnderline } from '../../icons';\r\n\r\nimport {type API, type InlineTool, type SanitizerConfig} from \"@ebl-vue/editorjs\";\r\nimport {type InlineToolConstructorOptions} from \"@ebl-vue/editorjs/types/tools/inline-tool\";\r\n\r\n/**\r\n * Underline Tool for the Editor.js\r\n *\r\n * Allows to wrap inline fragment and style it somehow.\r\n */\r\nexport default class Underline implements InlineTool {\r\n /**\r\n * Class name for term-tag\r\n *\r\n * @type {string}\r\n */\r\n static get CSS(): string {\r\n return 'cdx-underline';\r\n };\r\n\r\n /**\r\n * Toolbar Button\r\n *\r\n * @type {HTMLButtonElement}\r\n */\r\n private button: HTMLButtonElement | undefined\r\n\r\n /**\r\n * Tag represented the term\r\n *\r\n * @type {string}\r\n */\r\n private tag: string = 'U';\r\n\r\n /**\r\n * API InlineToolConstructorOptions\r\n *\r\n * @type {API}\r\n */\r\n private api: API\r\n\r\n /**\r\n * CSS classes\r\n *\r\n * @type {object}\r\n */\r\n private iconClasses: {base: string, active: string}\r\n\r\n /**\r\n * @param options InlineToolConstructorOptions\r\n */\r\n public constructor(options: InlineToolConstructorOptions) {\r\n this.api = options.api;\r\n\r\n /**\r\n * CSS classes\r\n */\r\n this.iconClasses = {\r\n base: this.api.styles.inlineToolButton,\r\n active: this.api.styles.inlineToolButtonActive,\r\n };\r\n }\r\n\r\n /**\r\n * Specifies Tool as Inline Toolbar Tool\r\n *\r\n * @returns {boolean}\r\n */\r\n public static isInline = true;\r\n\r\n /**\r\n * Create button element for Toolbar\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n public render(): HTMLElement {\r\n this.button = document.createElement('button');\r\n this.button.type = 'button';\r\n this.button.classList.add(this.iconClasses.base);\r\n this.button.innerHTML = this.toolboxIcon;\r\n\r\n return this.button;\r\n }\r\n\r\n /**\r\n * Wrap/Unwrap selected fragment\r\n *\r\n * @param {Range} range - selected fragment\r\n */\r\n public surround(range: Range): void {\r\n if (!range) {\r\n return;\r\n }\r\n\r\n const termWrapper = this.api.selection.findParentTag(this.tag, Underline.CSS);\r\n\r\n /**\r\n * If start or end of selection is in the highlighted block\r\n */\r\n if (termWrapper) {\r\n this.unwrap(termWrapper);\r\n } else {\r\n this.wrap(range);\r\n }\r\n }\r\n\r\n /**\r\n * Wrap selection with term-tag\r\n *\r\n * @param {Range} range - selected fragment\r\n */\r\n public wrap(range: Range) {\r\n /**\r\n * Create a wrapper for highlighting\r\n */\r\n const u = document.createElement(this.tag);\r\n\r\n u.classList.add(Underline.CSS);\r\n\r\n /**\r\n * SurroundContent throws an error if the Range splits a non-Text node with only one of its boundary points\r\n *\r\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Range/surroundContents}\r\n *\r\n * // range.surroundContents(span);\r\n */\r\n u.appendChild(range.extractContents());\r\n range.insertNode(u);\r\n\r\n /**\r\n * Expand (add) selection to highlighted block\r\n */\r\n this.api.selection.expandToTag(u);\r\n }\r\n\r\n /**\r\n * Unwrap term-tag\r\n *\r\n * @param {HTMLElement} termWrapper - term wrapper tag\r\n */\r\n public unwrap(termWrapper: HTMLElement): void {\r\n /**\r\n * Expand selection to all term-tag\r\n */\r\n this.api.selection.expandToTag(termWrapper);\r\n\r\n const sel = window.getSelection();\r\n if (!sel) {\r\n return;\r\n }\r\n const range = sel.getRangeAt(0);\r\n if (!range) {\r\n return\r\n }\r\n\r\n const unwrappedContent = range.extractContents();\r\n if (!unwrappedContent) {\r\n return\r\n }\r\n\r\n /**\r\n * Remove empty term-tag\r\n */\r\n termWrapper.parentNode?.removeChild(termWrapper);\r\n\r\n /**\r\n * Insert extracted content\r\n */\r\n range.insertNode(unwrappedContent);\r\n\r\n /**\r\n * Restore selection\r\n */\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n }\r\n\r\n /**\r\n * Check and change Term's state for current selection\r\n */\r\n public checkState(): boolean {\r\n const termTag = this.api.selection.findParentTag(this.tag, Underline.CSS);\r\n\r\n this.button?.classList.toggle(this.iconClasses.active, !!termTag);\r\n\r\n return !!termTag\r\n }\r\n\r\n /**\r\n * Get Tool icon's SVG\r\n *\r\n * @returns {string}\r\n */\r\n public get toolboxIcon(): string {\r\n return IconUnderline;\r\n }\r\n\r\n /**\r\n * Sanitizer rule\r\n *\r\n * @returns {{u: {class: string}}}\r\n */\r\n public static get sanitize(): SanitizerConfig {\r\n return {\r\n u: {\r\n class: Underline.CSS,\r\n },\r\n };\r\n }\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\nimport {IconBrackets} from '../../icons';\r\n\r\nimport { API, InlineTool, InlineToolConstructorOptions, SanitizerConfig } from \"@editorjs/editorjs\";\r\n\r\ninterface IconClasses {\r\n base: string;\r\n active: string;\r\n}\r\n\r\n/**\r\n * Inline Code Tool for the Editor.js\r\n *\r\n * Allows to wrap inline fragment and style it somehow.\r\n */\r\nexport default class InlineCode implements InlineTool {\r\n /**\r\n * Editor.js API\r\n */\r\n private api: API;\r\n /**\r\n * Button element for the toolbar\r\n */\r\n private button: HTMLButtonElement | null;\r\n /**\r\n * Tag representing the term\r\n */\r\n private tag: string = 'CODE';\r\n /**\r\n * CSS classes for the icon\r\n */\r\n private iconClasses: IconClasses;\r\n\r\n /**\r\n * Class name for term-tag\r\n *\r\n * @type {string}\r\n */\r\n static get CSS(): string {\r\n return 'inline-code';\r\n }\r\n\r\n constructor({ api }: InlineToolConstructorOptions) {\r\n this.api = api;\r\n\r\n this.button = null;\r\n\r\n this.iconClasses = {\r\n base: this.api.styles.inlineToolButton,\r\n active: this.api.styles.inlineToolButtonActive,\r\n };\r\n }\r\n\r\n /**\r\n * Specifies Tool as Inline Toolbar Tool\r\n *\r\n * @return {boolean}\r\n */\r\n static get isInline(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Create button element for Toolbar\r\n *\r\n * @return {HTMLElement}\r\n */\r\n render(): HTMLElement {\r\n this.button = document.createElement('button');\r\n this.button.type = 'button';\r\n this.button.classList.add(this.iconClasses.base);\r\n this.button.innerHTML = this.toolboxIcon;\r\n\r\n return this.button;\r\n }\r\n\r\n /**\r\n * Wrap/Unwrap selected fragment\r\n *\r\n * @param {Range} range - selected fragment\r\n */\r\n surround(range: Range): void {\r\n if (!range) {\r\n return;\r\n }\r\n\r\n let termWrapper = this.api.selection.findParentTag(this.tag, InlineCode.CSS) as HTMLElement;\r\n\r\n /**\r\n * If the start or end of the selection range is within a highlighted block\r\n */\r\n if (termWrapper) {\r\n this.unwrap(termWrapper);\r\n } else {\r\n const existingCodeTag = range.commonAncestorContainer.parentElement?.querySelector(this.tag);\r\n if (!existingCodeTag) {\r\n this.wrap(range);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Wrap selection with term-tag\r\n *\r\n * @param {Range} range - selected fragment\r\n */\r\n wrap(range: Range): void {\r\n /**\r\n * Create a wrapper for highlighting\r\n */\r\n let span = document.createElement(this.tag);\r\n\r\n span.classList.add(InlineCode.CSS);\r\n\r\n /**\r\n * SurroundContent throws an error if the Range splits a non-Text node with only one of its boundary points\r\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Range/surroundContents}\r\n *\r\n * // range.surroundContents(span);\r\n */\r\n span.appendChild(range.extractContents());\r\n range.insertNode(span);\r\n\r\n /**\r\n * Expand (add) selection to highlighted block\r\n */\r\n this.api.selection.expandToTag(span);\r\n }\r\n\r\n /**\r\n * Unwrap term-tag\r\n *\r\n * @param {HTMLElement} termWrapper - term wrapper tag\r\n */\r\n unwrap(termWrapper: HTMLElement): void {\r\n /**\r\n * Expand selection to all term-tag\r\n */\r\n this.api.selection.expandToTag(termWrapper);\r\n\r\n const sel = window.getSelection();\r\n if (!sel) return;\r\n\r\n const range = sel.getRangeAt(0);\r\n const unwrappedContent = range.extractContents();\r\n\r\n /**\r\n * Remove empty term-tag\r\n */\r\n termWrapper.parentNode?.removeChild(termWrapper);\r\n\r\n /**\r\n * Insert extracted content\r\n */\r\n range.insertNode(unwrappedContent);\r\n\r\n /**\r\n * Restore selection\r\n */\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n }\r\n\r\n /**\r\n * Check and change Term's state for current selection\r\n * \r\n * @return {boolean}\r\n */\r\n checkState(): boolean {\r\n const termTag = this.api.selection.findParentTag(this.tag, InlineCode.CSS);\r\n\r\n if (this.button) {\r\n this.button.classList.toggle(this.iconClasses.active, !!termTag);\r\n }\r\n\r\n return !!termTag;\r\n }\r\n\r\n\r\n /**\r\n * Get Tool icon's SVG\r\n * @return {string}\r\n */\r\n get toolboxIcon(): string {\r\n return IconBrackets;\r\n }\r\n\r\n /**\r\n * Sanitizer rule\r\n * @return {SanitizerConfig}\r\n */\r\n static get sanitize(): SanitizerConfig {\r\n return {\r\n code: {\r\n class: InlineCode.CSS,\r\n },\r\n };\r\n }\r\n}\r\n","/**\r\n * Helper for making Elements with attributes\r\n *\r\n * @param {string} tagName - new Element tag name\r\n * @param {string|string[]} classNames - list or name of CSS classname(s)\r\n * @param {object} attributes - any attributes\r\n * @returns {Element}\r\n */\r\nexport function make(\r\n tagName: string,\r\n classNames: string | string[],\r\n attributes:Record<string, any> = {}\r\n) {\r\n const el = document.createElement(tagName);\r\n\r\n if (Array.isArray(classNames)) {\r\n el.classList.add(...classNames);\r\n } else if (classNames) {\r\n el.classList.add(classNames);\r\n }\r\n\r\n for (const attrName in attributes) {\r\n if (!Object.prototype.hasOwnProperty.call(attributes, attrName)) {\r\n continue;\r\n }\r\n\r\n //el[attrName] = attributes[attrName];\r\n el.setAttribute(attrName, attributes[attrName]);\r\n }\r\n\r\n return el;\r\n}\r\n\r\n/**\r\n * Get item position relative to document\r\n *\r\n * @param {HTMLElement} elem - item\r\n * @returns {{x1: number, y1: number, x2: number, y2: number}} coordinates of the upper left (x1,y1) and lower right(x2,y2) corners\r\n */\r\nexport function getCoords(elem: HTMLElement) {\r\n const rect = elem.getBoundingClientRect();\r\n\r\n return {\r\n y1: Math.floor(rect.top + window.pageYOffset),\r\n x1: Math.floor(rect.left + window.pageXOffset),\r\n x2: Math.floor(rect.right + window.pageXOffset),\r\n y2: Math.floor(rect.bottom + window.pageYOffset)\r\n };\r\n}\r\n\r\n/**\r\n * Calculate paddings of the first element relative to the second\r\n *\r\n * @param {HTMLElement} firstElem - outer element, if the second element is inside it, then all padding will be positive\r\n * @param {HTMLElement} secondElem - inner element, if its borders go beyond the first, then the paddings will be considered negative\r\n * @returns {{fromTopBorder: number, fromLeftBorder: number, fromRightBorder: number, fromBottomBorder: number}}\r\n */\r\nexport function getRelativeCoordsOfTwoElems(firstElem: HTMLElement, secondElem: HTMLElement) {\r\n const firstCoords = getCoords(firstElem);\r\n const secondCoords = getCoords(secondElem);\r\n\r\n return {\r\n fromTopBorder: secondCoords.y1 - firstCoords.y1,\r\n fromLeftBorder: secondCoords.x1 - firstCoords.x1,\r\n fromRightBorder: firstCoords.x2 - secondCoords.x2,\r\n fromBottomBorder: firstCoords.y2 - secondCoords.y2\r\n };\r\n}\r\n\r\n/**\r\n * Get the width and height of an element and the position of the cursor relative to it\r\n *\r\n * @param {HTMLElement} elem - element relative to which the coordinates will be calculated\r\n * @param {Event} event - mouse event\r\n */\r\nexport function getCursorPositionRelativeToElement(elem: HTMLElement, event: MouseEvent) {\r\n const rect = elem.getBoundingClientRect();\r\n const { width, height, x, y } = rect;\r\n const { clientX, clientY } = event;\r\n\r\n return {\r\n width,\r\n height,\r\n x: clientX - x,\r\n y: clientY - y\r\n };\r\n}\r\n\r\n/**\r\n * Insert element after the referenced\r\n *\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} referenceNode\r\n * @returns {HTMLElement}\r\n */\r\nexport function insertAfter(newNode: HTMLElement, referenceNode: HTMLElement) {\r\n return referenceNode?.parentNode?.insertBefore(newNode, referenceNode.nextSibling);\r\n}\r\n\r\n/**\r\n * Insert element after the referenced\r\n *\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} referenceNode\r\n * @returns {HTMLElement}\r\n */\r\nexport function insertBefore(newNode: HTMLElement, referenceNode: HTMLElement) {\r\n return referenceNode?.parentNode?.insertBefore(newNode, referenceNode);\r\n}\r\n\r\n\r\n/**\r\n * Set focus to contenteditable or native input element\r\n *\r\n * @param {Element} element - element where to set focus\r\n * @param {boolean} atStart - where to set focus: at the start or at the end\r\n *\r\n * @returns {void}\r\n */\r\nexport function focus(element: HTMLElement, atStart = true) {\r\n const range = document.createRange();\r\n const selection = window.getSelection();\r\n\r\n range.selectNodeContents(element);\r\n range.collapse(atStart);\r\n\r\n selection?.removeAllRanges();\r\n selection?.addRange(range);\r\n}\r\n","import * as $ from './dom';\r\n\r\n/**\r\n * @typedef {object} PopoverItem\r\n * @property {string} label - button text\r\n * @property {string} icon - button icon\r\n * @property {boolean} confirmationRequired - if true, a confirmation state will be applied on the first click\r\n * @property {function} hideIf - if provided, item will be hid, if this method returns true\r\n * @property {function} onClick - click callback\r\n */\r\ninterface IPopoverItem {\r\n label: string;\r\n icon?: string;\r\n confirmationRequired?: boolean;\r\n hideIf?: () => boolean;\r\n onClick: () => void;\r\n}\r\n/**\r\n * This cass provides a popover rendering\r\n */\r\nexport default class Popover {\r\n private wrapper: HTMLElement|null|undefined;\r\n private items: IPopoverItem[];\r\n private itemEls: HTMLElement[];\r\n /**\r\n * @param {object} options - constructor options\r\n * @param {PopoverItem[]} options.items - constructor options\r\n */\r\n constructor({items}: {items: any}) {\r\n this.items = items;\r\n this.wrapper = undefined;\r\n this.itemEls = [];\r\n }\r\n\r\n /**\r\n * Set of CSS classnames used in popover\r\n *\r\n * @returns {object}\r\n */\r\n static get CSS() {\r\n return {\r\n popover: 'tc-popover',\r\n popoverOpened: 'tc-popover--opened',\r\n item: 'tc-popover__item',\r\n itemHidden: 'tc-popover__item--hidden',\r\n itemConfirmState: 'tc-popover__item--confirm',\r\n itemIcon: 'tc-popover__item-icon',\r\n itemLabel: 'tc-popover__item-label'\r\n };\r\n }\r\n\r\n /**\r\n * Returns the popover element\r\n *\r\n * @returns {Element}\r\n */\r\n render() {\r\n this.wrapper = $.make('div', Popover.CSS.popover);\r\n\r\n this.items.forEach((item:IPopoverItem, index:number) => {\r\n const itemEl = $.make('div', Popover.CSS.item);\r\n const icon = $.make('div', Popover.CSS.itemIcon, {\r\n innerHTML: item.icon\r\n });\r\n const label = $.make('div', Popover.CSS.itemLabel, {\r\n textContent: item.label\r\n });\r\n\r\n itemEl.dataset.index = index + '';\r\n \r\n\r\n itemEl.appendChild(icon);\r\n itemEl.appendChild(label);\r\n\r\n this.wrapper?.appendChild(itemEl);\r\n this.itemEls.push(itemEl);\r\n });\r\n\r\n /**\r\n * Delegate click\r\n */\r\n this.wrapper.addEventListener('click', (event) => {\r\n this.popoverClicked(event);\r\n });\r\n\r\n return this.wrapper;\r\n }\r\n\r\n /**\r\n * Popover wrapper click listener\r\n * Used to delegate clicks in items\r\n *\r\n * @returns {void}\r\n */\r\n popoverClicked(event: MouseEvent) {\r\n const target = event.target as HTMLElement;\r\n const clickedItem = target.closest(`.${Popover.CSS.item}`) as HTMLElement;\r\n\r\n /**\r\n * Clicks outside or between item\r\n */\r\n if (!clickedItem) {\r\n return;\r\n }\r\n\r\n const clickedItemIndex:string|undefined = clickedItem.dataset.index;\r\n if(!clickedItemIndex) return;\r\n\r\n const item = this.items[parseInt(clickedItemIndex)];\r\n\r\n if (item.confirmationRequired && !this.hasConfirmationState(clickedItem)) {\r\n this.setConfirmationState(clickedItem);\r\n\r\n return;\r\n }\r\n\r\n item.onClick();\r\n }\r\n\r\n /**\r\n * Enable the confirmation state on passed item\r\n *\r\n * @returns {void}\r\n */\r\n setConfirmationState(itemEl: HTMLElement) {\r\n itemEl.classList.add(Popover.CSS.itemConfirmState);\r\n }\r\n\r\n /**\r\n * Disable the confirmation state on passed item\r\n *\r\n * @returns {void}\r\n */\r\n clearConfirmationState(itemEl: HTMLElement) {\r\n itemEl.classList.remove(Popover.CSS.itemConfirmState);\r\n }\r\n\r\n /**\r\n * Check if passed item has the confirmation state\r\n *\r\n * @returns {boolean}\r\n */\r\n hasConfirmationState(itemEl: HTMLElement) {\r\n return itemEl.classList.contains(Popover.CSS.itemConfirmState);\r\n }\r\n\r\n /**\r\n * Return an opening state\r\n *\r\n * @returns {boolean}\r\n */\r\n get opened() {\r\n return this.wrapper?.classList.contains(Popover.CSS.popoverOpened) || false;\r\n }\r\n\r\n /**\r\n * Opens the popover\r\n *\r\n * @returns {void}\r\n */\r\n open() {\r\n /**\r\n * If item provides 'hideIf()' method that returns true, hide item\r\n */\r\n this.items.forEach((item, index) => {\r\n if (typeof item.hideIf === 'function') {\r\n this.itemEls[index].classList.toggle(Popover.CSS.itemHidden, item.hideIf());\r\n }\r\n });\r\n\r\n this.wrapper?.classList.add(Popover.CSS.popoverOpened);\r\n }\r\n\r\n /**\r\n * Closes the popover\r\n *\r\n * @returns {void}\r\n */\r\n close() {\r\n this.wrapper?.classList.remove(Popover.CSS.popoverOpened);\r\n this.itemEls.forEach(el => {\r\n this.clearConfirmationState(el);\r\n });\r\n }\r\n}\r\n","import Popover from \"./utils/popover\";\r\nimport * as $ from \"./utils/dom\";\r\nimport { IconMenuSmall } from \"../../icons\";\r\n\r\n/**\r\n * @typedef {object} PopoverItem\r\n * @property {string} label - button text\r\n * @property {string} icon - button icon\r\n * @property {boolean} confirmationRequired - if true, a confirmation state will be applied on the first click\r\n * @property {function} hideIf - if provided, item will be hid, if this method returns true\r\n * @property {function} onClick - click callback\r\n */\r\n\r\n/**\r\n * Toolbox is a menu for manipulation of rows/cols\r\n *\r\n * It contains toggler and Popover:\r\n * <toolbox>\r\n * <toolbox-toggler />\r\n * <popover />\r\n * <toolbox>\r\n */\r\nexport default class Toolbox {\r\n\r\n private items: any;\r\n private onOpen: any;\r\n private onClose: any;\r\n private cssModifier: string;\r\n private popover: Popover | null;\r\n private wrapper: HTMLElement;\r\n /**\r\n * Creates toolbox buttons and toolbox menus\r\n *\r\n * @param {Object} config\r\n * @param {any} config.api - Editor.js api\r\n * @param {PopoverItem[]} config.items - Editor.js api\r\n * @param {function} config.onOpen - callback fired when the Popover is opening\r\n * @param {function} config.onClose - callback fired when the Popover is closing\r\n * @param {string} config.cssModifier - the modifier for the Toolbox. Allows to add some specific styles.\r\n */\r\n constructor({ items, onOpen, onClose, cssModifier = \"\" }: any) {\r\n \r\n\r\n this.items = items;\r\n this.onOpen = onOpen;\r\n this.onClose = onClose;\r\n this.cssModifier = cssModifier;\r\n\r\n this.popover = null;\r\n this.wrapper = this.createToolbox();\r\n }\r\n\r\n /**\r\n * Style classes\r\n */\r\n static get CSS() {\r\n return {\r\n toolbox: \"tc-toolbox\",\r\n toolboxShowed: \"tc-toolbox--showed\",\r\n toggler: \"tc-toolbox__toggler\",\r\n };\r\n }\r\n\r\n /**\r\n * Returns rendered Toolbox element\r\n */\r\n get element() {\r\n return this.wrapper;\r\n }\r\n\r\n /**\r\n * Creating a toolbox to open menu for a manipulating columns\r\n *\r\n * @returns {Element}\r\n */\r\n createToolbox() {\r\n const wrapper = $.make(\"div\", [\r\n Toolbox.CSS.toolbox,\r\n this.cssModifier ? `${Toolbox.CSS.toolbox}--${this.cssModifier}` : \"\",\r\n ]);\r\n\r\n wrapper.dataset.mutationFree = \"true\";\r\n const popover = this.createPopover();\r\n const toggler = this.createToggler();\r\n\r\n wrapper.appendChild(toggler);\r\n wrapper.appendChild(popover);\r\n\r\n return wrapper;\r\n }\r\n\r\n /**\r\n * Creates the Toggler\r\n *\r\n * @returns {Element}\r\n */\r\n createToggler() {\r\n const toggler = $.make(\"div\", Toolbox.CSS.toggler, {\r\n innerHTML: IconMenuSmall,\r\n });\r\n\r\n toggler.addEventListener(\"click\", () => {\r\n this.togglerClicked();\r\n });\r\n\r\n return toggler;\r\n }\r\n\r\n /**\r\n * Creates the Popover instance and render it\r\n *\r\n * @returns {Element}\r\n */\r\n createPopover() {\r\n this.popover = new Popover({\r\n items: this.items,\r\n });\r\n\r\n return this.popover.render();\r\n }\r\n\r\n /**\r\n * Toggler click handler. Opens/Closes the popover\r\n *\r\n * @returns {void}\r\n */\r\n togglerClicked() {\r\n if (this.popover?.opened) {\r\n this.popover.close();\r\n this.onClose();\r\n } else {\r\n this.popover?.open();\r\n this.onOpen();\r\n }\r\n }\r\n\r\n /**\r\n * Shows the Toolbox\r\n *\r\n * @param {function} computePositionMethod - method that returns the position coordinate\r\n * @returns {void}\r\n */\r\n show(computePositionMethod:Function) {\r\n const position = computePositionMethod();\r\n\r\n /**\r\n * Set 'top' or 'left' style\r\n */\r\n Object.entries(position).forEach(([prop, value]) => {\r\n //this.wrapper.style[prop] = value;\r\n this.wrapper.style.setProperty(prop, value as string);\r\n });\r\n\r\n this.wrapper.classList.add(Toolbox.CSS.toolboxShowed);\r\n }\r\n\r\n /**\r\n * Hides the Toolbox\r\n *\r\n * @returns {void}\r\n */\r\n hide() {\r\n this.popover?.close();\r\n this.wrapper.classList.remove(Toolbox.CSS.toolboxShowed);\r\n }\r\n}\r\n","import Toolbox from './toolbox';\r\nimport * as $ from './utils/dom';\r\nimport throttled from './utils/throttled';\r\n\r\nimport {\r\n IconDirectionLeftDown,\r\n IconDirectionRightDown,\r\n IconDirectionUpRight,\r\n IconDirectionDownRight,\r\n IconCross,\r\n\r\n} from '../../icons';\r\ntype TableData = {\r\n /**\r\n * - number of rows in the table\r\n */\r\n /**\r\n * - number of rows in the table\r\n */\r\n rows: number;\r\n /**\r\n * - number of columns in the table\r\n */\r\n /**\r\n * - number of columns in the table\r\n */\r\n cols: number;\r\n colWidth: string[];\r\n}\r\nconst CSS = {\r\n wrapper: 'tc-wrap',\r\n wrapperReadOnly: 'tc-wrap--readonly',\r\n table: 'tc-table',\r\n row: 'tc-row',\r\n withHeadings: 'tc-table--heading',\r\n rowSelected: 'tc-row--selected',\r\n cell: 'tc-cell',\r\n cellSelected: 'tc-cell--selected',\r\n addRow: 'tc-add-row',\r\n addRowDisabled: 'tc-add-row--disabled',\r\n addColumn: 'tc-add-column',\r\n addColumnDisabled: 'tc-add-column--disabled',\r\n};\r\n\r\n/**\r\n * @typedef {object} TableConfig\r\n * @description Tool's config from Editor\r\n * @property {boolean} withHeadings — Uses the first line as headings\r\n * @property {string[][]} withHeadings — two-dimensional array with table contents\r\n */\r\n\r\n/**\r\n * @typedef {object} TableData - object with the data transferred to form a table\r\n * @property {number} rows - number of rows in the table\r\n * @property {number} cols - number of columns in the table\r\n */\r\n\r\n\r\n/**\r\n * Generates and manages table contents.\r\n */\r\nexport default class Table {\r\n\r\n private readOnly: boolean;\r\n private api: any;\r\n private data: any;\r\n private config: any;\r\n private wrapper: any;\r\n private table: any;\r\n private toolboxColumn: any;\r\n private toolboxRow: any;\r\n private documentClicked: any;\r\n private hoveredRow: any;\r\n private hoveredColumn: any;\r\n private selectedRow: any;\r\n private selectedColumn: any;\r\n private tunes: any;\r\n private focusedCell: any;\r\n\r\n private hoveredCell: any;\r\n private isDragging: boolean;\r\n //private draggingRow: number;\r\n private draggingColumn: number;\r\n //private draggingColArr: any[];\r\n private startWidth: number;\r\n private mouseStartX: number;\r\n private colWidthArr:any[];\r\n private minCellWidhth: number=50;\r\n private defaultCellWidth = 100;\r\n /**\r\n * Creates\r\n *\r\n * @constructor\r\n * @param {boolean} readOnly - read-only mode flag\r\n * @param {object} api - Editor.js API\r\n * @param {TableData} data - Editor.js API\r\n * @param {TableConfig} config - Editor.js API\r\n */\r\n constructor(readOnly: boolean, api: any, data: TableData, config: any) {\r\n this.readOnly = readOnly;\r\n this.api = api;\r\n this.data = data;\r\n this.config = config;\r\n\r\n /**\r\n * DOM nodes\r\n */\r\n this.wrapper = null;\r\n this.table = null;\r\n this.hoveredCell = null;\r\n\r\n this.isDragging = false;\r\n //this.draggingColArr = [];\r\n //this.draggingRow = 0;\r\n this.draggingColumn = 0;\r\n this.startWidth = 0;\r\n this.mouseStartX = 0;\r\n this.colWidthArr = [];\r\n \r\n\r\n // 鼠标焦点数据\r\n this.focusedCell = {\r\n row: 0,\r\n col: 0,\r\n };\r\n /**\r\n * Toolbox for managing of columns\r\n */\r\n this.toolboxColumn = this.createColumnToolbox();\r\n this.toolboxRow = this.createRowToolbox();\r\n\r\n /**\r\n * Create table and wrapper elements\r\n */\r\n this.createTableWrapper();\r\n\r\n // Current hovered row index\r\n this.hoveredRow = 0;\r\n\r\n // Current hovered column index\r\n this.hoveredColumn = 0;\r\n\r\n // Index of last selected row via toolbox\r\n this.selectedRow = 0;\r\n\r\n // Index of last selected column via toolbox\r\n this.selectedColumn = 0;\r\n\r\n // Additional settings for the table\r\n this.tunes = {\r\n withHeadings: false\r\n };\r\n\r\n /**\r\n * Resize table to match config/data size\r\n */\r\n this.resize();\r\n if(this.data.colWidth.length > 0) {\r\n this.colWidthArr = this.data.colWidth;\r\n }\r\n this.updateColWidth();\r\n /**\r\n * Fill the table with data\r\n */\r\n this.fill();\r\n\r\n /**\r\n * The cell in which the focus is currently located, if 0 and 0 then there is no focus\r\n * Uses to switch between cells with buttons\r\n */\r\n this.focusedCell = {\r\n row: 0,\r\n column: 0\r\n };\r\n\r\n /**\r\n * Global click listener allows to delegate clicks on some elements\r\n */\r\n this.documentClicked = (event: MouseEvent) => {\r\n let target = event.target as HTMLElement;\r\n const clickedInsideTable = target.closest(`.${CSS.table}`) !== null;\r\n const outsideTableClicked = target.closest(`.${CSS.wrapper}`) === null;\r\n const clickedOutsideToolboxes = clickedInsideTable || outsideTableClicked;\r\n\r\n if (clickedOutsideToolboxes) {\r\n this.hideToolboxes();\r\n }\r\n\r\n const clickedOnAddRowButton = target.closest(`.${CSS.addRow}`);\r\n const clickedOnAddColumnButton = target.closest(`.${CSS.addColumn}`);\r\n\r\n /**\r\n * Also, check if clicked in current table, not other (because documentClicked bound to the whole document)\r\n */\r\n if (clickedOnAddRowButton && clickedOnAddRowButton.parentNode === this.wrapper) {\r\n this.addRow(undefined, true);\r\n this.hideToolboxes();\r\n } else if (clickedOnAddColumnButton && clickedOnAddColumnButton.parentNode === this.wrapper) {\r\n this.addColumn(undefined, true);\r\n this.hideToolboxes();\r\n }\r\n };\r\n\r\n if (!this.readOnly) {\r\n this.bindEvents();\r\n }\r\n }\r\n\r\n /**\r\n * Returns the rendered table wrapper\r\n *\r\n * @returns {Element}\r\n */\r\n getWrapper() {\r\n return this.wrapper;\r\n }\r\n\r\n /**\r\n * Hangs the necessary handlers to events\r\n */\r\n bindEvents() {\r\n // set the listener to close toolboxes when click outside\r\n document.addEventListener('click', this.documentClicked);\r\n// 鼠标点击事件:判定是否在表格内部\r\n document.addEventListener(\"mousedown\", (e) =>\r\n this.handleDocumentMousedown(e)\r\n );\r\n // Update toolboxes position depending on the mouse movements\r\n this.table.addEventListener('mousemove', throttled(150, (event:MouseEvent) => this.onMouseMoveInTable(event)), { passive: true });\r\n\r\n // Controls some of the keyboard buttons inside the table\r\n this.table.onkeypress = (event:KeyboardEvent) => this.onKeyPressListener(event);\r\n\r\n // Tab is executed by default before keypress, so it must be intercepted on keydown\r\n this.table.addEventListener('keydown', (event:KeyboardEvent) => this.onKeyDownListener(event));\r\n\r\n // Determine the position of the cell in focus\r\n this.table.addEventListener('focusin', (event:FocusEvent) => this.focusInTableListener(event));\r\n }\r\nhandleDocumentMousedown = (e:MouseEvent) => {\r\n // 在表格内部按下鼠标并且处于拖拽位置\r\n if (this.wrapper.contains(e.target)) {\r\n const target = e.target as HTMLElement;\r\n if (target.classList.contains(\"cell-resizable\")) {\r\n e.preventDefault();\r\n //this.hideToolbox(); // 拖拽时隐藏工具栏\r\n this.isDragging = true;\r\n this.table.classList.add(\"table-resizing\"); //为整个表格添加光标样式\r\n document.addEventListener(\"mousemove\", this.handleDocumentMousemove);\r\n document.addEventListener(\"mouseup\", this.handleDocumentMouseup);\r\n //this.draggingRow = this.hoveredRow;\r\n this.draggingColumn = this.hoveredColumn;\r\n //this.draggingColArr = this.getCellInCol(this.draggingColumn);\r\n this.startWidth = this.colWidthArr[this.draggingColumn - 1]; //获取初始宽度\r\n this.mouseStartX = e.clientX;\r\n }\r\n } else {\r\n //this.hideToolbox();\r\n }\r\n };\r\n // 获取同一列的所有单元格\r\n getCellInCol(col:number) {\r\n const cells:any[] = [];\r\n const rows = this.table.querySelectorAll(`.${CSS.row}`);\r\n rows.forEach((row:Element) => {\r\n const cell = row.querySelector(`.${CSS.cell}:nth-child(${col})`);\r\n if (cell) cells.push(cell);\r\n });\r\n return cells;\r\n }\r\n // mousemove事件\r\n handleDocumentMousemove = (e:MouseEvent) => {\r\n if (!this.isDragging) return;\r\n const currentMouseX = e.clientX;\r\n const deltaX = currentMouseX - this.mouseStartX;\r\n const newWidth = Math.max(this.startWidth + deltaX, this.minCellWidhth);\r\n\r\n this.colWidthArr[this.draggingColumn - 1] = newWidth;\r\n this.updateColWidth();\r\n };\r\n // mouseup事件\r\n handleDocumentMouseup = () => {\r\n //this.showToolbox(); // 拖拽结束时重新显示工具栏\r\n //this.updateToolboxPosition();\r\n this.updateToolboxesPosition();\r\n this.isDragging = false;\r\n this.table.classList.remove(\"table-resizing\");\r\n document.removeEventListener(\"mousemove\", this.handleDocumentMousemove);\r\n document.removeEventListener(\"mouseup\", this.handleDocumentMouseup);\r\n };\r\n /**\r\n * Configures and creates the toolbox for manipulating with columns\r\n *\r\n * @returns {Toolbox}\r\n */\r\n createColumnToolbox() {\r\n return new Toolbox({\r\n api: this.api,\r\n cssModifier: 'column',\r\n items: [\r\n {\r\n label: this.api.i18n.t('Add column to left'),\r\n icon: IconDirectionLeftDown,\r\n hideIf: () => {\r\n return this.numberOfColumns === this.config.maxcols\r\n },\r\n onClick: () => { \r\n this.addColumn(this.selectedColumn, true);\r\n this.hideToolboxes();\r\n this.updateColWidth();\r\n }\r\n },\r\n {\r\n label: this.api.i18n.t('Add column to right'),\r\n icon: IconDirectionRightDown,\r\n hideIf: () => {\r\n return this.numberOfColumns === this.config.maxcols\r\n },\r\n onClick: () => {\r\n this.addColumn(this.selectedColumn + 1, true);\r\n this.hideToolboxes();\r\n this.updateColWidth();\r\n }\r\n },\r\n {\r\n label: this.api.i18n.t('Delete column'),\r\n icon: IconCross,\r\n hideIf: () => {\r\n return this.numberOfColumns === 1;\r\n },\r\n confirmationRequired: true,\r\n onClick: () => {\r\n this.deleteColumn(this.selectedColumn);\r\n this.hideToolboxes();\r\n this.updateColWidth();\r\n }\r\n }\r\n ],\r\n onOpen: () => {\r\n this.selectColumn(this.hoveredColumn);\r\n this.hideRowToolbox();\r\n },\r\n onClose: () => {\r\n this.unselectColumn();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Configures and creates the toolbox for manipulating with rows\r\n *\r\n * @returns {Toolbox}\r\n */\r\n createRowToolbox() {\r\n return new Toolbox({\r\n api: this.api,\r\n cssModifier: 'row',\r\n items: [\r\n {\r\n label: this.api.i18n.t('Add row above'),\r\n icon: IconDirectionUpRight,\r\n hideIf: () => {\r\n return this.numberOfRows === this.config.maxrows\r\n },\r\n onClick: () => {\r\n this.addRow(this.selectedRow, true);\r\n this.hideToolboxes();\r\n }\r\n },\r\n {\r\n label: this.api.i18n.t('Add row below'),\r\n icon: IconDirectionDownRight,\r\n hideIf: () => {\r\n return this.numberOfRows === this.config.maxrows\r\n },\r\n onClick: () => {\r\n this.addRow(this.selectedRow + 1, true);\r\n this.hideToolboxes();\r\n }\r\n },\r\n {\r\n label: this.api.i18n.t('Delete row'),\r\n icon: IconCross,\r\n hideIf: () => {\r\n return this.numberOfRows === 1;\r\n },\r\n confirmationRequired: true,\r\n onClick: () => {\r\n this.deleteRow(this.selectedRow);\r\n this.hideToolboxes();\r\n }\r\n }\r\n ],\r\n onOpen: () => {\r\n this.selectRow(this.hoveredRow);\r\n this.hideColumnToolbox();\r\n },\r\n onClose: () => {\r\n this.unselectRow();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * When you press enter it moves the cursor down to the next row\r\n * or creates it if the click occurred on the last one\r\n */\r\n moveCursorToNextRow() {\r\n if (this.focusedCell.row !== this.numberOfRows) {\r\n this.focusedCell.row += 1;\r\n //this.focusCell(this.focusedCell);\r\n this.focusCell();\r\n } else {\r\n this.addRow();\r\n this.focusedCell.row += 1;\r\n //this.focusCell(this.focusedCell);\r\n this.focusCell();\r\n this.updateToolboxesPosition(0, 0);\r\n }\r\n }\r\n\r\n /**\r\n * Get table cell by row and col index\r\n *\r\n * @param {number} row - cell row coordinate\r\n * @param {number} column - cell column coordinate\r\n * @returns {HTMLElement}\r\n */\r\n getCell(row:number, column:number) {\r\n return this.table.querySelectorAll(`.${CSS.row}:nth-child(${row}) .${CSS.cell}`)[column - 1];\r\n }\r\n\r\n /**\r\n * Get table row by index\r\n *\r\n * @param {number} row - row coordinate\r\n * @returns {HTMLElement}\r\n */\r\n getRow(row:number) {\r\n return this.table.querySelector(`.${CSS.row}:nth-child(${row})`);\r\n }\r\n\r\n /**\r\n * The parent of the cell which is the row\r\n *\r\n * @param {HTMLElement} cell - cell element\r\n * @returns {HTMLElement}\r\n */\r\n getRowByCell(cell:HTMLElement) {\r\n return cell.parentElement;\r\n }\r\n\r\n /**\r\n * Ger row's first cell\r\n *\r\n * @param {Element} row - row to find its first cell\r\n * @returns {Element}\r\n */\r\n getRowFirstCell(row:Element) {\r\n return row.querySelector(`.${CSS.cell}:first-child`);\r\n }\r\n\r\n /**\r\n * Set the sell's content by row and column numbers\r\n *\r\n * @param {number} row - cell row coordinate\r\n * @param {number} column - cell column coordinate\r\n * @param {string} content - cell HTML content\r\n */\r\n setCellContent(row:number, column:number, content:string) {\r\n const cell = this.getCell(row, column);\r\n\r\n cell.innerHTML = content;\r\n }\r\n\r\n /**\r\n * Add column in table on index place\r\n * Add cells in each row\r\n *\r\n * @param {number} columnIndex - number in the array of columns, where new column to insert, -1 if insert at the end\r\n * @param {boolean} [setFocus] - pass true to focus the first cell\r\n */\r\n addColumn(columnIndex = -1, setFocus = false) {\r\n let numOfColumns=this.numberOfColumns;\r\n /**\r\n * Check if the number of columns has reached the maximum allowed columns specified in the configuration,\r\n * and if so, exit the function to prevent adding more columns beyond the limit.\r\n */\r\n if (this.config && this.config.maxcols && this.numberOfColumns >= this.config.maxcols) {\r\n return;\r\n }\r\n\r\n /**\r\n * Iterate all rows and add a new cell to them for creating a column\r\n */\r\n for (let rowIndex = 1; rowIndex <= this.numberOfRows; rowIndex++) {\r\n let cell;\r\n const cellElem = this.createCell();\r\n\r\n if (columnIndex > 0 && columnIndex <= numOfColumns) {\r\n cell = this.getCell(rowIndex, columnIndex);\r\n\r\n $.insertBefore(cellElem, cell);\r\n } else {\r\n cell = this.getRow(rowIndex).appendChild(cellElem);\r\n }\r\n\r\n /**\r\n * Autofocus first cell\r\n */\r\n if (rowIndex === 1) {\r\n const firstCell = this.getCell(rowIndex, columnIndex > 0 ? columnIndex : numOfColumns + 1);\r\n\r\n if (firstCell && setFocus) {\r\n $.focus(firstCell);\r\n }\r\n }\r\n }\r\n\r\n const addColButton = this.wrapper.querySelector(`.${CSS.addColumn}`);\r\n if (this.config?.maxcols && this.numberOfColumns > this.config.maxcols - 1 && addColButton ){\r\n addColButton.classList.add(CSS.addColumnDisabled);\r\n }\r\n this.addHeadingAttrToFirstRow();\r\n this.colWidthArr.splice(columnIndex - 1, 0, this.defaultCellWidth);\r\n };\r\n\r\n /**\r\n * Add row in table on index place\r\n *\r\n * @param {number} index - number in the array of rows, where new column to insert, -1 if insert at the end\r\n * @param {boolean} [setFocus] - pass true to focus the inserted row\r\n * @returns {HTMLElement} row\r\n */\r\n addRow(index = -1, setFocus = false) {\r\n let insertedRow;\r\n let rowElem = $.make('div', CSS.row);\r\n\r\n if (this.tunes.withHeadings) {\r\n this.removeHeadingAttrFromFirstRow();\r\n }\r\n\r\n /**\r\n * We remember the number of columns, because it is calculated\r\n * by the number of cells in the first row\r\n * It is necessary that the first line is filled in correctly\r\n */\r\n let numberOfColumns = this.numberOfColumns;\r\n /**\r\n * Check if the number of rows has reached the maximum allowed rows specified in the configuration,\r\n * and if so, exit the function to prevent adding more columns beyond the limit.\r\n */ \r\n if (this.config && this.config.maxrows && this.numberOfRows >= this.config.maxrows ) {\r\n return;\r\n }\r\n\r\n if (index > 0 && index <= this.numberOfRows) {\r\n let row = this.getRow(index);\r\n\r\n insertedRow = $.insertBefore(rowElem, row);\r\n } else {\r\n insertedRow = this.table.appendChild(rowElem);\r\n }\r\n\r\n this.fillRow(insertedRow, numberOfColumns);\r\n\r\n if (this.tunes.withHeadings) {\r\n this.addHeadingAttrToFirstRow();\r\n }\r\n\r\n const insertedRowFirstCell = this.getRowFirstCell(insertedRow);\r\n\r\n if (insertedRowFirstCell && setFocus) {\r\n $.focus(insertedRowFirstCell as HTMLElement);\r\n }\r\n\r\n const addRowButton = this.wrapper.querySelector(`.${CSS.addRow}`);\r\n if (this.config && this.config.maxrows && this.numberOfRows >= this.config.maxrows && addRowButton) {\r\n addRowButton.classList.add(CSS.addRowDisabled);\r\n }\r\n return insertedRow;\r\n };\r\n\r\n /**\r\n * Delete a column by index\r\n *\r\n * @param {number} index\r\n */\r\n deleteColumn(index: number) {\r\n for (let i = 1; i <= this.numberOfRows; i++) {\r\n const cell = this.getCell(i, index);\r\n\r\n if (!cell) {\r\n return;\r\n }\r\n\r\n cell.remove();\r\n }\r\n const addColButton = this.wrapper.querySelector(`.${CSS.addColumn}`);\r\n if (addColButton) {\r\n addColButton.classList.remove(CSS.addColumnDisabled);\r\n }\r\n this.colWidthArr.splice(index - 1, 1);\r\n }\r\n\r\n /**\r\n * Delete a row by index\r\n *\r\n * @param {number} index\r\n */\r\n deleteRow(index: number) {\r\n this.getRow(index).remove();\r\n const addRowButton = this.wrapper.querySelector(`.${CSS.addRow}`);\r\n if (addRowButton) {\r\n addRowButton.classList.remove(CSS.addRowDisabled);\r\n }\r\n\r\n this.addHeadingAttrToFirstRow();\r\n }\r\n\r\n /**\r\n * Create a wrapper containing a table, toolboxes\r\n * and buttons for adding rows and columns\r\n *\r\n * @returns {HTMLElement} wrapper - where all buttons for a table and the table itself will be\r\n */\r\n createTableWrapper() {\r\n this.wrapper = $.make('div', CSS.wrapper);\r\n this.table = $.make('div', CSS.table);\r\n\r\n if (this.readOnly) {\r\n this.wrapper.classList.add(CSS.wrapperReadOnly);\r\n }\r\n\r\n this.wrapper.appendChild(this.toolboxRow.element);\r\n this.wrapper.appendChild(this.toolboxColumn.element);\r\n this.wrapper.appendChild(this.table);\r\n\r\n // if (!this.readOnly) {\r\n // const addColumnButton = $.make('div', CSS.addColumn, {\r\n // innerHTML: IconPlus\r\n // });\r\n // const addRowButton = $.make('div', CSS.addRow, {\r\n // innerHTML: IconPlus\r\n // });\r\n\r\n // this.wrapper.appendChild(addColumnButton);\r\n // this.wrapper.appendChild(addRowButton);\r\n // }\r\n }\r\n\r\n /**\r\n * Returns the size of the table based on initial data or config \"size\" property\r\n *\r\n * @return {{rows: number, cols: number}} - number of cols and rows\r\n */\r\n computeInitialSize() {\r\n const content = this.data && this.data.content;\r\n const isValidArray = Array.isArray(content);\r\n const isNotEmptyArray = isValidArray ? content.length : false;\r\n const contentRows = isValidArray ? content.length : undefined;\r\n const contentCols = isNotEmptyArray ? content[0].length : undefined;\r\n const parsedRows = Number.parseInt(this.config && this.config.rows);\r\n const parsedCols = Number.parseInt(this.config && this.config.cols);\r\n\r\n /**\r\n * Value of config have to be positive number\r\n */\r\n const configRows = !isNaN(parsedRows) && parsedRows > 0 ? parsedRows : undefined;\r\n const configCols = !isNaN(parsedCols) && parsedCols > 0 ? parsedCols : undefined;\r\n const defaultRows = 2;\r\n const defaultCols = 2;\r\n const rows = contentRows || configRows || defaultRows;\r\n const cols = contentCols || configCols || defaultCols;\r\n\r\n return {\r\n rows: rows,\r\n cols: cols\r\n };\r\n }\r\n\r\n /**\r\n * Resize table to match config size or transmitted data size\r\n *\r\n * @return {{rows: number, cols: number}} - number of cols and rows\r\n */\r\n resize() {\r\n const { rows, cols } = this.computeInitialSize();\r\n\r\n for (let i = 0; i < rows; i++) {\r\n this.addRow();\r\n }\r\n\r\n for (let i = 0; i < cols; i++) {\r\n this.addColumn();\r\n }\r\n\r\n \r\n }\r\n updateColWidth() {\r\n //设置各列宽度\r\n let colWidth = \"\";\r\n if (this.colWidthArr && this.colWidthArr.length > 0) {\r\n for (let i = 0; i < this.colWidthArr.length; i++) {\r\n colWidth += \" \" + this.colWidthArr[i] + \"px\";\r\n }\r\n }\r\n if (colWidth) {\r\n this.wrapper.style.setProperty('--col-width', colWidth);\r\n }\r\n \r\n }\r\n\r\n /**\r\n * Fills the table with data passed to the constructor\r\n *\r\n * @returns {void}\r\n */\r\n fill() {\r\n const data = this.data;\r\n\r\n if (data && data.content) {\r\n for (let i = 0; i < data.content.length; i++) {\r\n for (let j = 0; j < data.content[i].length; j++) {\r\n this.setCellContent(i + 1, j + 1, data.content[i][j]);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Fills a row with cells\r\n *\r\n * @param {HTMLElement} row - row to fill\r\n * @param {number} numOfColumns - how many cells should be in a row\r\n */\r\n fillRow(row:HTMLElement, numOfColumns:number) {\r\n for (let i = 1; i <= numOfColumns; i++) {\r\n const newCell = this.createCell();\r\n\r\n row.appendChild(newCell);\r\n }\r\n }\r\n\r\n /**\r\n * Creating a cell element\r\n *\r\n * @return {Element}\r\n */\r\n createCell() {\r\n return $.make('div', CSS.cell, {\r\n contentEditable: !this.readOnly\r\n });\r\n }\r\n\r\n /**\r\n * Get number of rows in the table\r\n */\r\n get numberOfRows() {\r\n return this.table.childElementCount;\r\n }\r\n\r\n /**\r\n * Get number of columns in the table\r\n */\r\n get numberOfColumns() {\r\n if (this.numberOfRows) {\r\n return this.table.querySelectorAll(`.${CSS.row}:first-child .${CSS.cell}`).length;\r\n }\r\n\r\n return 0;\r\n }\r\n\r\n /**\r\n * Is the column toolbox menu displayed or not\r\n *\r\n * @returns {boolean}\r\n */\r\n get isColumnMenuShowing() {\r\n return this.selectedColumn !== 0;\r\n }\r\n\r\n /**\r\n * Is the row toolbox menu displayed or not\r\n *\r\n * @returns {boolean}\r\n */\r\n get isRowMenuShowing() {\r\n return this.selectedRow !== 0;\r\n }\r\n\r\n /**\r\n * Recalculate position of toolbox icons\r\n *\r\n * @param {Event} event - mouse move event\r\n */\r\n onMouseMoveInTable(event:MouseEvent) {\r\n const { row, column, deltaXCell } = this.getHoveredCell(event);\r\n\r\n this.hoveredColumn = column;\r\n this.hoveredRow = row;\r\n\r\n this.updateToolboxesPosition();\r\n\r\n if (this.hoveredCell !== null && this.hoveredCell.classList.contains(\"cell-resizable\")) {\r\n this.hoveredCell.classList.remove(\"cell-resizable\");\r\n }\r\n this.hoveredCell = this.getCell(row, column);\r\n \r\n // 判断是否可以调整列宽\r\n if (this.cellIsResizable(this.hoveredCell, deltaXCell)) {\r\n // 将鼠标改为拖拽光标\r\n if (!this.hoveredCell.classList.contains(\"cell-resizable\"))\r\n this.hoveredCell.classList.add(\"cell-resizable\");\r\n }\r\n\r\n }\r\n cellIsResizable(cell: HTMLElement, deltaX: number) {\r\n // 判断光标是否在单元格右侧10px的位置\r\n const cellWidth = cell.clientWidth;\r\n return cellWidth - deltaX <= 10;\r\n }\r\n /**\r\n * Prevents default Enter behaviors\r\n * Adds Shift+Enter processing\r\n *\r\n * @param {KeyboardEvent} event - keypress event\r\n */\r\n onKeyPressListener(event: KeyboardEvent) {\r\n if (event.key === 'Enter') {\r\n if (event.shiftKey) {\r\n return true;\r\n }\r\n\r\n this.moveCursorToNextRow();\r\n }\r\n\r\n return event.key !== 'Enter';\r\n };\r\n\r\n /**\r\n * Prevents tab keydown event from bubbling\r\n * so that it only works inside the table\r\n *\r\n * @param {KeyboardEvent} event - keydown event\r\n */\r\n onKeyDownListener(event: KeyboardEvent) {\r\n if (event.key === 'Tab') {\r\n event.stopPropagation();\r\n }\r\n }\r\n\r\n /**\r\n * Set the coordinates of the cell that the focus has moved to\r\n *\r\n * @param {FocusEvent} event - focusin event\r\n */\r\n focusInTableListener(event: FocusEvent) {\r\n const cell = event.target as HTMLElement;\r\n const row = this.getRowByCell(cell);\r\n if(!row) return;\r\n\r\n this.focusedCell = {\r\n row: Array.from(this.table.querySelectorAll(`.${CSS.row}`)).indexOf(row) + 1,\r\n column: Array.from(row.querySelectorAll(`.${CSS.cell}`)).indexOf(cell) + 1\r\n };\r\n }\r\n\r\n /**\r\n * Unselect row/column\r\n * Close toolbox menu\r\n * Hide toolboxes\r\n *\r\n * @returns {void}\r\n */\r\n hideToolboxes() {\r\n this.hideRowToolbox();\r\n this.hideColumnToolbox();\r\n this.updateToolboxesPosition();\r\n }\r\n\r\n /**\r\n * Unselect row, close toolbox\r\n *\r\n * @returns {void}\r\n */\r\n hideRowToolbox() {\r\n this.unselectRow();\r\n this.toolboxRow.hide();\r\n }\r\n /**\r\n * Unselect column, close toolbox\r\n *\r\n * @returns {void}\r\n */\r\n hideColumnToolbox() {\r\n this.unselectColumn();\r\n\r\n this.toolboxColumn.hide();\r\n }\r\n\r\n /**\r\n * Set the cursor focus to the focused cell\r\n *\r\n * @returns {void}\r\n */\r\n focusCell() {\r\n this.focusedCellElem.focus();\r\n }\r\n\r\n /**\r\n * Get current focused element\r\n *\r\n * @returns {HTMLElement} - focused cell\r\n */\r\n get focusedCellElem() {\r\n const { row, column } = this.focusedCell;\r\n\r\n return this.getCell(row, column);\r\n }\r\n\r\n /**\r\n * Update toolboxes position\r\n *\r\n * @param {number} row - hovered row\r\n * @param {number} column - hovered column\r\n */\r\n updateToolboxesPosition(row = this.hoveredRow, column = this.hoveredColumn) {\r\n if (!this.isColumnMenuShowing) {\r\n if (column > 0 && column <= this.numberOfColumns) { // not sure this statement is needed. Maybe it should be fixed in getHoveredCell()\r\n this.toolboxColumn.show(() => {\r\n return {\r\n left: `calc((100% - var(--cell-size)) / (${this.numberOfColumns} * 2) * (1 + (${column} - 1) * 2))`\r\n };\r\n });\r\n }\r\n }\r\n\r\n if (!this.isRowMenuShowing) {\r\n if (row > 0 && row <= this.numberOfRows) { // not sure this statement is needed. Maybe it should be fixed in getHoveredCell()\r\n this.toolboxRow.show(() => {\r\n const hoveredRowElement = this.getRow(row);\r\n const { fromTopBorder } = $.getRelativeCoordsOfTwoElems(this.table, hoveredRowElement);\r\n const { height } = hoveredRowElement.getBoundingClientRect();\r\n\r\n return {\r\n top: `${Math.ceil(fromTopBorder + height / 2)}px`\r\n };\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Makes the first row headings\r\n *\r\n * @param {boolean} withHeadings - use headings row or not\r\n */\r\n setHeadingsSetting(withHeadings: boolean) {\r\n this.tunes.withHeadings = withHeadings;\r\n\r\n if (withHeadings) {\r\n this.table.classList.add(CSS.withHeadings);\r\n this.addHeadingAttrToFirstRow();\r\n } else {\r\n this.table.classList.remove(CSS.withHeadings);\r\n this.removeHeadingAttrFromFirstRow();\r\n }\r\n }\r\n\r\n /**\r\n * Adds an attribute for displaying the placeholder in the cell\r\n */\r\n addHeadingAttrToFirstRow() {\r\n for (let cellIndex = 1; cellIndex <= this.numberOfColumns; cellIndex++) {\r\n let cell = this.getCell(1, cellIndex);\r\n\r\n if (cell) {\r\n cell.setAttribute('heading', this.api.i18n.t('Heading'));\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Removes an attribute for displaying the placeholder in the cell\r\n */\r\n removeHeadingAttrFromFirstRow() {\r\n for (let cellIndex = 1; cellIndex <= this.numberOfColumns; cellIndex++) {\r\n let cell = this.getCell(1, cellIndex);\r\n\r\n if (cell) {\r\n cell.removeAttribute('heading');\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Add effect of a selected row\r\n *\r\n * @param {number} index\r\n */\r\n selectRow(index: number) {\r\n const row = this.getRow(index);\r\n\r\n if (row) {\r\n this.selectedRow = index;\r\n row.classList.add(CSS.rowSelected);\r\n }\r\n }\r\n\r\n /**\r\n * Remove effect of a selected row\r\n */\r\n unselectRow() {\r\n if (this.selectedRow <= 0) {\r\n return;\r\n }\r\n\r\n const row = this.table.querySelector(`.${CSS.rowSelected}`);\r\n\r\n if (row) {\r\n row.classList.remove(CSS.rowSelected);\r\n }\r\n\r\n this.selectedRow = 0;\r\n }\r\n\r\n /**\r\n * Add effect of a selected column\r\n *\r\n * @param {number} index\r\n */\r\n selectColumn(index: number) {\r\n for (let i = 1; i <= this.numberOfRows; i++) {\r\n const cell = this.getCell(i, index);\r\n\r\n if (cell) {\r\n cell.classList.add(CSS.cellSelected);\r\n }\r\n }\r\n\r\n this.selectedColumn = index;\r\n }\r\n\r\n /**\r\n * Remove effect of a selected column\r\n */\r\n unselectColumn() {\r\n if (this.selectedColumn <= 0) {\r\n return;\r\n }\r\n\r\n let cells = this.table.querySelectorAll(`.${CSS.cellSelected}`) as HTMLElement[];\r\n\r\n Array.from(cells).forEach((column: HTMLElement) => {\r\n column.classList.remove(CSS.cellSelected);\r\n });\r\n\r\n this.selectedColumn = 0;\r\n }\r\n\r\n /**\r\n * Calculates the row and column that the cursor is currently hovering over\r\n * The search was optimized from O(n) to O (log n) via bin search to reduce the number of calculations\r\n *\r\n * @param {Event} event - mousemove event\r\n * @returns hovered cell coordinates as an integer row and column\r\n */\r\n getHoveredCell(event: MouseEvent) {\r\n let hoveredRow = this.hoveredRow;\r\n let hoveredColumn = this.hoveredColumn;\r\n const { width, height, x, y } = $.getCursorPositionRelativeToElement(this.table, event);\r\n \r\n\r\n \r\n // Looking for hovered column\r\n if (x >= 0) {\r\n const beforeTheLeftBorder1 = ({ fromLeftBorder }: { fromLeftBorder: number }) => x < fromLeftBorder;\r\n const afterTheRightBorder1 = ({ fromRightBorder }: { fromRightBorder: number }) => x > (width - fromRightBorder);\r\n hoveredColumn = this.binSearch(\r\n this.numberOfColumns,\r\n (mid: number) => this.getCell(1, mid),\r\n beforeTheLeftBorder1,\r\n afterTheRightBorder1\r\n );\r\n }\r\n\r\n // Looking for hovered row\r\n if (y >= 0) {\r\n const beforeTheLeftBorder2 = ({ fromTopBorder }: { fromTopBorder: number }) => y < fromTopBorder;\r\n const afterTheRightBorder2 = ({ fromBottomBorder }: { fromBottomBorder: number }) => y > (height - fromBottomBorder);\r\n hoveredRow = this.binSearch(\r\n this.numberOfRows,\r\n (mid: number) => this.getCell(mid, 1),\r\n beforeTheLeftBorder2,\r\n afterTheRightBorder2\r\n );\r\n }\r\n const row = hoveredRow || this.hoveredRow;\r\n const column = hoveredColumn || this.hoveredColumn;\r\n // 获取鼠标在单元格内的坐标\r\n const { deltaXCell, deltaYCell } = this.getMousePositionRelateToCell(\r\n row,\r\n column,\r\n x,\r\n y\r\n );\r\n\r\n return {\r\n row,\r\n column,\r\n deltaXCell,\r\n deltaYCell\r\n };\r\n }\r\n // 获取鼠标相对于单元格的坐标\r\n getMousePositionRelateToCell(row:number, col:number, deltaX:number, deltaY:number) {\r\n const cell = this.getCell(row, col);\r\n const { fromTopBorder, fromLeftBorder } = $.getRelativeCoordsOfTwoElems(\r\n this.table,\r\n cell\r\n );\r\n return {\r\n deltaXCell: deltaX - fromLeftBorder,\r\n deltaYCell: deltaY - fromTopBorder,\r\n };\r\n }\r\n /**\r\n * Looks for the index of the cell the mouse is hovering over.\r\n * Cells can be represented as ordered intervals with left and\r\n * right (upper and lower for rows) borders inside the table, if the mouse enters it, then this is our index\r\n *\r\n * @param {number} numberOfCells - upper bound of binary search\r\n * @param {function} getCell - function to take the currently viewed cell\r\n * @param {function} beforeTheLeftBorder - determines the cursor position, to the left of the cell or not\r\n * @param {function} afterTheRightBorder - determines the cursor position, to the right of the cell or not\r\n * @returns {number}\r\n */\r\n binSearch(numberOfCells: number, getCell: Function, beforeTheLeftBorder: Function, afterTheRightBorder: Function) {\r\n let leftBorder = 0;\r\n let rightBorder = numberOfCells + 1;\r\n let totalIterations = 0;\r\n let mid;\r\n\r\n while (leftBorder < rightBorder - 1 && totalIterations < 10) {\r\n mid = Math.ceil((leftBorder + rightBorder) / 2);\r\n\r\n const cell = getCell(mid);\r\n const relativeCoords = $.getRelativeCoordsOfTwoElems(this.table, cell);\r\n\r\n if (beforeTheLeftBorder(relativeCoords)) {\r\n rightBorder = mid;\r\n } else if (afterTheRightBorder(relativeCoords)) {\r\n leftBorder = mid;\r\n } else {\r\n break;\r\n }\r\n\r\n totalIterations++;\r\n }\r\n\r\n return mid;\r\n }\r\n\r\n /**\r\n * Collects data from cells into a two-dimensional array\r\n *\r\n * @returns {string[][]}\r\n */\r\n getData() {\r\n const data = [];\r\n\r\n for (let i = 1; i <= this.numberOfRows; i++) {\r\n const row = this.table.querySelector(`.${CSS.row}:nth-child(${i})`);\r\n const cells = Array.from(row.querySelectorAll(`.${CSS.cell}`));\r\n const isEmptyRow = cells.every((cell:any)=>!cell.textContent.trim());\r\n\r\n if (isEmptyRow) {\r\n continue;\r\n }\r\n\r\n data.push(cells.map((cell:any) => cell.innerHTML));\r\n }\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * Remove listeners on the document\r\n */\r\n destroy() {\r\n document.removeEventListener('click', this.documentClicked);\r\n }\r\n}","\r\n/**\r\n * Limits the frequency of calling a function\r\n *\r\n * @param {number} delay - delay between calls in milliseconds\r\n * @param {function} fn - function to be throttled\r\n */\r\nexport default function throttled(delay:number, fn:Function) {\r\n let lastCall = 0;\r\n\r\n return function (...args) {\r\n const now = new Date().getTime();\r\n\r\n if (now - lastCall < delay) {\r\n return;\r\n }\r\n\r\n lastCall = now;\r\n\r\n return fn(...args);\r\n };\r\n}\r\n","import Table from './table';\r\nimport * as $ from './utils/dom';\r\n\r\nimport { IconTable, IconTableWithHeadings, IconTableWithoutHeadings } from '../../icons';\r\nimport type { BlockTool, BlockToolConstructorOptions,PasteEvent } from '@ebl-vue/editorjs';\r\n\r\n/**\r\n * @typedef {object} TableData - configuration that the user can set for the table\r\n * @property {number} rows - number of rows in the table\r\n * @property {number} cols - number of columns in the table\r\n */\r\n/**\r\n * @typedef {object} Tune - setting for the table\r\n * @property {string} name - tune name\r\n * @property {HTMLElement} icon - icon for the tune\r\n * @property {boolean} isActive - default state of the tune\r\n * @property {void} setTune - set tune state to the table data\r\n */\r\n/**\r\n * @typedef {object} TableConfig - object with the data transferred to form a table\r\n * @property {boolean} withHeading - setting to use cells of the first row as headings\r\n * @property {string[][]} content - two-dimensional array which contains table content\r\n */\r\n/**\r\n * @typedef {object} TableConstructor\r\n * @property {TableConfig} data — previously saved data\r\n * @property {TableConfig} config - user config for Tool\r\n * @property {object} api - Editor.js API\r\n * @property {boolean} readOnly - read-only mode flag\r\n */\r\n/**\r\n * @typedef {import('@editorjs/editorjs').PasteEvent} PasteEvent\r\n */\r\n\r\n\r\n/**\r\n * Table block for Editor.js\r\n */\r\nexport default class TableBlock implements BlockTool {\r\n private api: any;\r\n private data: any;\r\n private config: any;\r\n private container: any;\r\n //private block: any;\r\n private readOnly: any;\r\n private table: any;\r\n \r\n /**\r\n * Notify core that read-only mode is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Allow to press Enter inside the CodeTool textarea\r\n *\r\n * @returns {boolean}\r\n * @public\r\n */\r\n static get enableLineBreaks() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {TableConstructor} init\r\n */\r\n constructor({ data, config, api, readOnly, block }: BlockToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n this.config = config;\r\n this.data = {\r\n withHeadings: this.getConfig('withHeadings', undefined, data),\r\n stretched: this.getConfig('stretched', undefined, data),\r\n content: data && data.content ? data.content : [],\r\n colWidth: data && data.colWidth ? data.colWidth : []\r\n };\r\n this.table = null;\r\n //this.block = block;\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @returns {{icon: string, title: string}}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: IconTable,\r\n title: 'Table'\r\n };\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLDivElement}\r\n */\r\n render() {\r\n /** creating table */\r\n this.table = new Table(this.readOnly, this.api, this.data, this.config);\r\n\r\n /** creating container around table */\r\n this.container = $.make('div', this.api.styles.block);\r\n \r\n this.container.appendChild(this.table.getWrapper());\r\n\r\n this.table.setHeadingsSetting(this.data.withHeadings);\r\n\r\n return this.container;\r\n }\r\n\r\n /**\r\n * Returns plugin settings\r\n *\r\n * @returns {Array}\r\n */\r\n renderSettings() {\r\n return [\r\n {\r\n label: this.api.i18n.t('With headings'),\r\n icon: IconTableWithHeadings,\r\n isActive: this.data.withHeadings,\r\n closeOnActivate: true,\r\n toggle: true,\r\n hint: {\r\n title: this.api.i18n.t('With headings')\r\n },\r\n onActivate: () => {\r\n this.data.withHeadings = true;\r\n this.table.setHeadingsSetting(this.data.withHeadings);\r\n }\r\n }, {\r\n label: this.api.i18n.t('Without headings'),\r\n icon: IconTableWithoutHeadings,\r\n isActive: !this.data.withHeadings,\r\n closeOnActivate: true,\r\n toggle: true,\r\n hint: {\r\n title: this.api.i18n.t('Without headings')\r\n },\r\n onActivate: () => {\r\n this.data.withHeadings = false;\r\n this.table.setHeadingsSetting(this.data.withHeadings);\r\n }\r\n },\r\n // {\r\n // label: this.data.stretched ? this.api.i18n.t('Collapse') : this.api.i18n.t('Stretch'),\r\n // icon: this.data.stretched ? IconCollapse : IconStretch,\r\n // closeOnActivate: true,\r\n // toggle: true,\r\n // onActivate: () => {\r\n // this.data.stretched = !this.data.stretched;\r\n // this.block.stretched = this.data.stretched;\r\n // }\r\n // }\r\n ];\r\n }\r\n /**\r\n * Extract table data from the view\r\n *\r\n * @returns {TableData} - saved data\r\n */\r\n save() {\r\n const tableContent = this.table.getData();\r\n\r\n const result = {\r\n withHeadings: this.data.withHeadings,\r\n stretched: this.data.stretched,\r\n content: tableContent\r\n };\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Plugin destroyer\r\n *\r\n * @returns {void}\r\n */\r\n destroy() {\r\n this.table.destroy();\r\n }\r\n\r\n /**\r\n * A helper to get config value.\r\n *\r\n * @param {string} configName - the key to get from the config.\r\n * @param {any} defaultValue - default value if config doesn't have passed key\r\n * @param {object} savedData - previously saved data. If passed, the key will be got from there, otherwise from the config\r\n * @returns {any} - config value.\r\n */\r\n getConfig(configName: string, defaultValue = undefined, savedData = undefined) {\r\n const data = this.data || savedData;\r\n\r\n if (data) {\r\n return data[configName] ? data[configName] : defaultValue;\r\n }\r\n\r\n return this.config && this.config[configName] ? this.config[configName] : defaultValue;\r\n }\r\n\r\n /**\r\n * Table onPaste configuration\r\n *\r\n * @public\r\n */\r\n static get pasteConfig() {\r\n return { tags: ['TABLE', 'TR', 'TH', 'TD'] };\r\n }\r\n\r\n /**\r\n * On paste callback that is fired from Editor\r\n *\r\n * @param {PasteEvent} event - event with pasted data\r\n */\r\n onPaste(event: PasteEvent) {\r\n if ('data' in event.detail) {\r\n const table = event.detail.data as HTMLElement;\r\n\r\n /** Check if the first row is a header */\r\n const firstRowHeading = table.querySelector(':scope > thead, tr:first-of-type th');\r\n\r\n /** Get all rows from the table */\r\n const rows = Array.from(table.querySelectorAll('tr'));\r\n\r\n /** Generate a content matrix */\r\n const content = rows.map((row) => {\r\n /** Get cells from row */\r\n const cells = Array.from(row.querySelectorAll('th, td'))\r\n\r\n /** Return cells content */\r\n return cells.map((cell) => cell.innerHTML);\r\n });\r\n\r\n /** Update Tool's data */\r\n this.data = {\r\n withHeadings: firstRowHeading !== null,\r\n content\r\n };\r\n\r\n /** Update table block */\r\n if (this.table.wrapper) {\r\n this.table.wrapper.replaceWith(this.render());\r\n }\r\n }\r\n }\r\n}\r\n","/**\r\n * Helper for making Elements with attributes\r\n * @param tagName - new Element tag name\r\n * @param classNames - list or name of CSS class\r\n * @param attributes - any attributes\r\n * @returns\r\n */\r\nexport function make(tagName: string, classNames: string[] | string | null = null, attributes: { [key: string]: string | boolean } = {}): HTMLElement {\r\n const el = document.createElement(tagName);\r\n\r\n if (Array.isArray(classNames)) {\r\n el.classList.add(...classNames);\r\n } else if (classNames !== null) {\r\n el.classList.add(classNames);\r\n }\r\n\r\n for (const attrName in attributes) {\r\n if (attributes.hasOwnProperty(attrName)) {\r\n (el as unknown as { [key: string]: string | boolean })[attrName] = attributes[attrName];\r\n }\r\n }\r\n\r\n return el;\r\n}\r\n","import { IconPicture } from '../../icons';\r\nimport { make } from './utils/dom';\r\nimport type { API } from '@editorjs/editorjs';\r\nimport type { ImageConfig } from './types/types';\r\n\r\n/**\r\n * Enumeration representing the different states of the UI.\r\n */\r\nexport enum UiState {\r\n /**\r\n * The UI is in an empty state, with no image loaded or being selected.\r\n */\r\n Empty = 'empty',\r\n\r\n /**\r\n * The UI is in an uploading state, indicating an image is currently being uploaded.\r\n */\r\n Uploading = 'uploading',\r\n\r\n /**\r\n * The UI is in a filled state, with an image successfully loaded.\r\n */\r\n Filled = 'filled'\r\n};\r\n\r\n/**\r\n * Nodes interface representing various elements in the UI.\r\n */\r\ninterface Nodes {\r\n /**\r\n * Wrapper element in the UI.\r\n */\r\n wrapper: HTMLElement;\r\n\r\n /**\r\n * Container for the image element in the UI.\r\n */\r\n imageContainer: HTMLElement;\r\n\r\n /**\r\n * Button for selecting files.\r\n */\r\n fileButton: HTMLElement;\r\n\r\n /**\r\n * Represents the image element in the UI, if one is present; otherwise, it's undefined.\r\n */\r\n imageEl?: HTMLElement;\r\n\r\n /**\r\n * Preloader element for the image.\r\n */\r\n imagePreloader: HTMLElement;\r\n\r\n /**\r\n * Caption element for the image.\r\n */\r\n caption: HTMLElement;\r\n}\r\n\r\n/**\r\n * ConstructorParams interface representing parameters for the Ui class constructor.\r\n */\r\ninterface ConstructorParams {\r\n /**\r\n * Editor.js API.\r\n */\r\n api: API;\r\n /**\r\n * Configuration for the image.\r\n */\r\n config: ImageConfig;\r\n /**\r\n * Callback function for selecting a file.\r\n */\r\n onSelectFile: () => void;\r\n /**\r\n * Flag indicating if the UI is in read-only mode.\r\n */\r\n readOnly: boolean;\r\n}\r\n\r\n/**\r\n * Class for working with UI:\r\n * - rendering base structure\r\n * - show/hide preview\r\n * - apply tune view\r\n */\r\nexport default class Ui {\r\n /**\r\n * Nodes representing various elements in the UI.\r\n */\r\n public nodes: Nodes;\r\n\r\n /**\r\n * API instance for Editor.js.\r\n */\r\n private api: API;\r\n\r\n /**\r\n * Configuration for the image tool.\r\n */\r\n private config: ImageConfig;\r\n\r\n /**\r\n * Callback function for selecting a file.\r\n */\r\n private onSelectFile: () => void;\r\n\r\n /**\r\n * Flag indicating if the UI is in read-only mode.\r\n */\r\n private readOnly: boolean;\r\n\r\n /**\r\n * @param ui - image tool Ui module\r\n * @param ui.api - Editor.js API\r\n * @param ui.config - user config\r\n * @param ui.onSelectFile - callback for clicks on Select file button\r\n * @param ui.readOnly - read-only mode flag\r\n */\r\n constructor({ api, config, onSelectFile, readOnly }: ConstructorParams) {\r\n this.api = api;\r\n this.config = config;\r\n this.onSelectFile = onSelectFile;\r\n \r\n this.readOnly = readOnly;\r\n this.nodes = {\r\n wrapper: make('div', [this.CSS.baseClass, this.CSS.wrapper]),\r\n imageContainer: make('div', [this.CSS.imageContainer]),\r\n fileButton: this.createFileButton(),\r\n imageEl: undefined,\r\n imagePreloader: make('div', this.CSS.imagePreloader),\r\n caption: make('div', [this.CSS.input, this.CSS.caption], {\r\n contentEditable: !this.readOnly,\r\n }),\r\n };\r\n\r\n /**\r\n * Create base structure\r\n * <wrapper>\r\n * <image-container>\r\n * <image-preloader />\r\n * </image-container>\r\n * <caption />\r\n * <select-file-button />\r\n * </wrapper>\r\n */\r\n this.nodes.caption.dataset.placeholder = this.config.captionPlaceholder;\r\n this.nodes.imageContainer.appendChild(this.nodes.imagePreloader);\r\n this.nodes.wrapper.appendChild(this.nodes.imageContainer);\r\n this.nodes.wrapper.appendChild(this.nodes.caption);\r\n this.nodes.wrapper.appendChild(this.nodes.fileButton);\r\n }\r\n\r\n /**\r\n * Apply visual representation of activated tune\r\n * @param tuneName - one of available tunes {@link Tunes.tunes}\r\n * @param status - true for enable, false for disable\r\n */\r\n public applyTune(tuneName: string, status: boolean): void {\r\n this.nodes.wrapper.classList.toggle(`${this.CSS.wrapper}--${tuneName}`, status);\r\n }\r\n\r\n /**\r\n * Renders tool UI\r\n */\r\n public render(): HTMLElement {\r\n this.toggleStatus(UiState.Empty);\r\n\r\n return this.nodes.wrapper;\r\n }\r\n\r\n /**\r\n * Shows uploading preloader\r\n * @param src - preview source\r\n */\r\n public showPreloader(src: string): void {\r\n this.nodes.imagePreloader.style.backgroundImage = `url(${src})`;\r\n\r\n //this.toggleStatus(UiState.Uploading);\r\n }\r\n \r\n\r\n /**\r\n * Hide uploading preloader\r\n */\r\n public hidePreloader(): void {\r\n this.nodes.imagePreloader.style.backgroundImage = '';\r\n this.toggleStatus(UiState.Empty);\r\n }\r\n\r\n /**\r\n * Shows an image\r\n * @param url - image source\r\n */\r\n public fillImage(url: string): void {\r\n /**\r\n * Check for a source extension to compose element correctly: video tag for mp4, img — for others\r\n */\r\n const tag = /\\.mp4$/.test(url) ? 'VIDEO' : 'IMG';\r\n\r\n const attributes: { [key: string]: string | boolean } = {\r\n src: url,\r\n };\r\n\r\n /**\r\n * We use eventName variable because IMG and VIDEO tags have different event to be called on source load\r\n * - IMG: load\r\n * - VIDEO: loadeddata\r\n */\r\n let eventName = 'load';\r\n\r\n /**\r\n * Update attributes and eventName if source is a mp4 video\r\n */\r\n if (tag === 'VIDEO') {\r\n /**\r\n * Add attributes for playing muted mp4 as a gif\r\n */\r\n attributes.autoplay = true;\r\n attributes.loop = true;\r\n attributes.muted = true;\r\n attributes.playsinline = true;\r\n\r\n /**\r\n * Change event to be listened\r\n */\r\n eventName = 'loadeddata';\r\n }\r\n\r\n /**\r\n * Compose tag with defined attributes\r\n */\r\n this.nodes.imageEl = make(tag, this.CSS.imageEl, attributes);\r\n\r\n /**\r\n * Add load event listener\r\n */\r\n this.nodes.imageEl.addEventListener(eventName, () => {\r\n this.toggleStatus(UiState.Filled);\r\n\r\n /**\r\n * Preloader does not exists on first rendering with presaved data\r\n */\r\n if (this.nodes.imagePreloader !== undefined) {\r\n this.nodes.imagePreloader.style.backgroundImage = '';\r\n }\r\n });\r\n\r\n this.nodes.imageContainer.appendChild(this.nodes.imageEl);\r\n }\r\n\r\n /**\r\n * Shows caption input\r\n * @param text - caption content text\r\n */\r\n public fillCaption(text: string): void {\r\n if (this.nodes.caption !== undefined) {\r\n this.nodes.caption.innerHTML = text;\r\n }\r\n }\r\n\r\n /**\r\n * Changes UI status\r\n * @param status - see {@link Ui.status} constants\r\n */\r\n public toggleStatus(status: UiState): void {\r\n for (const statusType in UiState) {\r\n if (Object.prototype.hasOwnProperty.call(UiState, statusType)) {\r\n const state = UiState[statusType as keyof typeof UiState];\r\n\r\n this.nodes.wrapper.classList.toggle(`${this.CSS.wrapper}--${state}`, state === status);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * CSS classes\r\n */\r\n private get CSS(): Record<string, string> {\r\n return {\r\n baseClass: this.api.styles.block,\r\n loading: this.api.styles.loader,\r\n input: this.api.styles.input,\r\n button: this.api.styles.button,\r\n\r\n /**\r\n * Tool's classes\r\n */\r\n wrapper: 'image-tool',\r\n imageContainer: 'image-tool__image',\r\n imagePreloader: 'image-tool__image-preloader',\r\n imageEl: 'image-tool__image-picture',\r\n caption: 'image-tool__caption',\r\n };\r\n };\r\n\r\n /**\r\n * Creates upload-file button\r\n */\r\n private createFileButton(): HTMLElement {\r\n const button = make('div', [this.CSS.button]);\r\n\r\n button.innerHTML = this.config.buttonContent ?? `${IconPicture} ${this.api.i18n.t('Select an Image')}`;\r\n\r\n button.addEventListener('click', () => {\r\n this.onSelectFile();\r\n });\r\n\r\n return button;\r\n }\r\n}\r\n","\r\nimport isPromise from './utils/isPromise';\r\nimport type { IUploadResponseFormat, UploadOptions } from './types/types';\r\nimport type { UploadResponseFormat, ImageConfig } from './types/types';\r\nimport axios, { AxiosInstance } from \"axios\";\r\nimport { selectFiles } from './utils/index';\r\n/**\r\n * Params interface for Uploader constructor\r\n */\r\ninterface UploaderParams {\r\n /**\r\n * Configuration for the uploader\r\n */\r\n config: ImageConfig;\r\n\r\n /**\r\n * Handles the upload response.\r\n * @param {UploadResponseFormat} response - Response format expected from the backend on file uploading.\r\n * @returns {void}\r\n */\r\n onUpload: (response: UploadResponseFormat) => void;\r\n\r\n /**\r\n *\r\n * @param error : error type\r\n * @returns void\r\n */\r\n onError: (error: string) => void;\r\n}\r\n\r\n/**\r\n * Module for file uploading. Handle 3 scenarios:\r\n * 1. Select file from device and upload\r\n * 2. Upload by pasting URL\r\n * 3. Upload by pasting file from Clipboard or by Drag'n'Drop\r\n */\r\nexport default class Uploader {\r\n private config: ImageConfig;\r\n private onUpload: (response: UploadResponseFormat) => void;\r\n private onError: (error: string) => void;\r\n /**\r\n * @param params - uploader module params\r\n * @param params.config - image tool config\r\n * @param params.onUpload - one callback for all uploading (file, url, d-n-d, pasting)\r\n * @param params.onError - callback for uploading errors\r\n */\r\n constructor({ config, onUpload, onError }: UploaderParams) {\r\n this.config = config;\r\n this.onUpload = onUpload;\r\n this.onError = onError;\r\n }\r\n\r\n /**\r\n * Handle clicks on the upload file button\r\n * Fires ajax.transport()\r\n * @param onPreview - callback fired when preview is ready\r\n */\r\n public async uploadSelectedFile({ onPreview, noSelectedFile }: UploadOptions) {\r\n\r\n const preparePreview = function (file: File): void {\r\n const reader = new FileReader();\r\n\r\n reader.readAsDataURL(file);\r\n reader.onload = (e) => {\r\n onPreview((e.target as FileReader).result as string);\r\n };\r\n };\r\n\r\n /**\r\n * Custom uploading\r\n * or default uploading\r\n */\r\n\r\n let cdn: string = \"\";\r\n let objectKey: string = \"\";\r\n\r\n\r\n\r\n //选获取上传文件的地址\r\n const files = await selectFiles({ accept: this.config.types ?? 'image/*' });\r\n\r\n if (files && files.length > 0) {\r\n preparePreview(files[0]);\r\n } else {\r\n noSelectedFile();\r\n return\r\n }\r\n const file = files[0];\r\n const fileTypes = this.config.types.split(\",\");\r\n let suffixIndex = file.name.lastIndexOf(\".\");\r\n let suffix = file.name.slice(suffixIndex);\r\n\r\n if (!fileTypes.includes(suffix.toLowerCase())) {\r\n this.onError(\"文件类型不支持\");\r\n return;\r\n }\r\n\r\n let headers: Record<string, string> = {};\r\n if (this.config.userStore) {\r\n const token = this.config.userStore.token;\r\n const tokenName = this.config.userStore.tokenName;\r\n const tokenPrefix = this.config.userStore.tokenPrefix;\r\n if (token && tokenName) {\r\n headers[tokenName] = tokenPrefix + \" \" + token\r\n }\r\n }\r\n const axiosInstance: AxiosInstance = axios.create({\r\n timeout: 1800000,\r\n headers: headers,\r\n });\r\n headers[\"Content-Type\"] = \"application/json\";\r\n\r\n const uploadBodyRes = await axiosInstance.post(this.config.endpoints.byFile!, {\r\n \"fileName\": file.name,\r\n \"contentType\": file.type\r\n })\r\n if (uploadBodyRes.status !== 200) {\r\n this.onError(uploadBodyRes.statusText);\r\n return;\r\n }\r\n const uploadRes = uploadBodyRes.data;\r\n if (!uploadRes.success) {\r\n this.onError(uploadRes.message!);\r\n return;\r\n }\r\n console.log(uploadRes);\r\n cdn = uploadRes.data.cdn;\r\n objectKey = uploadRes.data.objectKey;\r\n\r\n\r\n headers[\"Content-Type\"] = file.type;\r\n\r\n let upload = axiosInstance.put(uploadRes.data.presignedUrl, file);\r\n\r\n\r\n\r\n\r\n upload.then((response) => {\r\n if (response.status === 200) {\r\n response = {\r\n success: 1,\r\n file: { url: cdn + objectKey }\r\n }\r\n }\r\n this.onUpload(response);\r\n }).catch((error: string) => {\r\n this.onError(error);\r\n });\r\n }\r\n\r\n /**\r\n * Handle clicks on the upload file button\r\n * Fires ajax.post()\r\n * @param url - image source url\r\n */\r\n public uploadByUrl(url: string): void {\r\n let upload;\r\n let headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\r\n if (this.config.userStore) {\r\n const token = this.config.userStore.token;\r\n const tokenName = this.config.userStore.tokenName;\r\n const tokenPrefix = this.config.userStore.tokenPrefix;\r\n if (token && tokenName) {\r\n headers[tokenName] = tokenPrefix + \" \" + token\r\n }\r\n }\r\n const axiosInstance: AxiosInstance = axios.create({\r\n timeout: 1800000,\r\n headers: headers,\r\n });\r\n upload = axiosInstance.post(this.config.endpoints.byUrl!, {\r\n \"url\": url,\r\n \"accept\": \".jpg,.jpeg,.gif,.png,.webp\"\r\n })\r\n\r\n\r\n\r\n\r\n upload.then((response) => {\r\n \r\n if(response.status !== 200||response.data.success===false){\r\n this.onError(response.data.message!);\r\n return;\r\n }\r\n \r\n let cdn = response.data.data.cdn;\r\n let objectKey = response.data.data.objectKey;\r\n\r\n let res = {\r\n success: 1,\r\n file: { url: cdn + objectKey }\r\n };\r\n this.onUpload(res);\r\n }).catch((error: string) => {\r\n this.onError(error);\r\n });\r\n\r\n }\r\n\r\n /**\r\n * Handle clicks on the upload file button\r\n * Fires ajax.post()\r\n * @param file - file pasted by drag-n-drop\r\n * @param onPreview - file pasted by drag-n-drop\r\n */\r\n public async uploadByFile(file: Blob, { onPreview }: UploadOptions) {\r\n\r\n\r\n const fileTypes = this.config.types.split(\",\");\r\n\r\n let suffixIndex = file.name.lastIndexOf(\".\");\r\n let suffix = file.name.slice(suffixIndex);\r\n\r\n if (!fileTypes.includes(suffix.toLowerCase())) {\r\n this.onError(\"文件类型不支持\");\r\n return;\r\n }\r\n\r\n\r\n\r\n let headers: Record<string, string> = {};\r\n if (this.config.userStore) {\r\n const token = this.config.userStore.token;\r\n const tokenName = this.config.userStore.tokenName;\r\n const tokenPrefix = this.config.userStore.tokenPrefix;\r\n if (token && tokenName) {\r\n headers[tokenName] = tokenPrefix + \" \" + token\r\n }\r\n }\r\n const axiosInstance: AxiosInstance = axios.create({\r\n timeout: 1800000,\r\n headers: headers,\r\n });\r\n headers[\"Content-Type\"] = \"application/json\";\r\n\r\n const uploadBodyRes = await axiosInstance.post(this.config.endpoints.byFile!, {\r\n \"fileName\": file.name,\r\n \"contentType\": file.type\r\n })\r\n if (uploadBodyRes.status !== 200) {\r\n this.onError(uploadBodyRes.statusText);\r\n return;\r\n }\r\n const uploadRes = uploadBodyRes.data;\r\n if (!uploadRes.success) {\r\n this.onError(uploadRes.message!);\r\n return;\r\n }\r\n console.log(uploadRes);\r\n let cdn = uploadRes.data.cdn;\r\n let objectKey = uploadRes.data.objectKey;\r\n\r\n\r\n headers[\"Content-Type\"] = file.type;\r\n let upload = axiosInstance.put(uploadRes.data.presignedUrl, file);\r\n upload.then((response) => {\r\n if (response.status === 200) {\r\n response = {\r\n success: 1,\r\n file: { url: cdn + objectKey }\r\n }\r\n }\r\n this.onUpload(response);\r\n }).catch((error: string) => {\r\n this.onError(error);\r\n });\r\n }\r\n}\r\n"," interface IConfig {\r\n multiple?: boolean;\r\n accept?: string;\r\n }\r\nexport function selectFiles(config = {} as IConfig): Promise<File[]> {\r\n let fileCancle = true;\r\n return new Promise((resolve, reject) => {\r\n /**\r\n * Create a new INPUT element\r\n * @type {HTMLElement}\r\n */\r\n let inputElement = document.createElement('INPUT');\r\n\r\n /**\r\n * Set a 'FILE' type for this input element\r\n * @type {string}\r\n */\r\n inputElement.type = 'file';\r\n\r\n if (config.multiple) {\r\n inputElement.setAttribute('multiple', 'multiple');\r\n }\r\n\r\n if (config.accept) {\r\n inputElement.setAttribute('accept', config.accept);\r\n }\r\n\r\n /**\r\n * Do not show element\r\n */\r\n inputElement.style.display = 'none';\r\n\r\n /**\r\n * Append element to the body\r\n * Fix using module on mobile devices\r\n */\r\n document.body.appendChild(inputElement);\r\n\r\n /**\r\n * Add onchange listener for «choose file» pop-up\r\n */\r\n inputElement.addEventListener('change', event => {\r\n console.log(\"选中文件\")\r\n fileCancle = false;\r\n /**\r\n * Get files from input field\r\n */\r\n const files = event.target.files;\r\n\r\n /**\r\n * Return ready to be uploaded files array\r\n */\r\n resolve(files);\r\n\r\n /**\r\n * Remove element from a DOM\r\n */\r\n document.body.removeChild(inputElement);\r\n }, false);\r\n window.addEventListener(\"focus\", () => { \r\n setTimeout(() => {\r\n if (fileCancle) {\r\n console.log(\"取消选择文件\")\r\n resolve([]);\r\n }\r\n }, 1000)\r\n },{once: true})\r\n /**\r\n * Fire click event on «input file» field\r\n */\r\n inputElement.click();\r\n });\r\n };","/**\r\n * Image Tool for the Editor.js\r\n * @author CodeX <team@codex.so>\r\n * @license MIT\r\n * @see {@link https://github.com/editor-js/image}\r\n *\r\n * To developers.\r\n * To simplify Tool structure, we split it to 4 parts:\r\n * 1) index.ts — main Tool's interface, public API and methods for working with data\r\n * 2) uploader.ts — module that has methods for sending files via AJAX: from device, by URL or File pasting\r\n * 3) ui.ts — module for UI manipulations: render, showing preloader, etc\r\n *\r\n * For debug purposes there is a testing server\r\n * that can save uploaded files and return a Response {@link UploadResponseFormat}\r\n *\r\n * $ node dev/server.js\r\n *\r\n * It will expose 8008 port, so you can pass http://localhost:8008 with the Tools config:\r\n *\r\n * image: {\r\n * class: ImageTool,\r\n * config: {\r\n * endpoints: {\r\n * byFile: 'http://localhost:8008/uploadFile',\r\n * byUrl: 'http://localhost:8008/fetchUrl',\r\n * }\r\n * },\r\n * },\r\n */\r\n\r\nimport type { TunesMenuConfig } from '@ebl-vue/editorjs/types/tools';\r\nimport type { API, ToolboxConfig, PasteConfig, BlockToolConstructorOptions, BlockTool, BlockAPI, PasteEvent, PatternPasteEventDetail, FilePasteEventDetail } from '@editorjs/editorjs';\r\nimport './index.css';\r\n\r\nimport Ui from './ui';\r\nimport Uploader from './uploader';\r\n\r\nimport { IconAddBorder, IconStretch, IconAddBackground, IconPicture, IconText } from '../../icons';\r\nimport type { ActionConfig, UploadResponseFormat, ImageToolData, ImageConfig, HTMLPasteEventDetailExtended, ImageSetterParam, FeaturesConfig } from './types/types';\r\n\r\ntype ImageToolConstructorOptions = BlockToolConstructorOptions<ImageToolData, ImageConfig>;\r\n\r\n/**\r\n * Implementation of ImageTool class\r\n */\r\nexport default class ImageTool implements BlockTool {\r\n /**\r\n * Editor.js API instance\r\n */\r\n private api: API;\r\n\r\n /**\r\n * Current Block API instance\r\n */\r\n private block: BlockAPI;\r\n\r\n /**\r\n * Configuration for the ImageTool\r\n */\r\n private config: ImageConfig;\r\n\r\n /**\r\n * Uploader module instance\r\n */\r\n private uploader: any;\r\n\r\n /**\r\n * UI module instance\r\n */\r\n private ui: Ui;\r\n\r\n /**\r\n * Stores current block data internally\r\n */\r\n private _data: ImageToolData;\r\n\r\n private userStore:any;\r\n\r\n\r\n /**\r\n * Caption enabled state\r\n * Null when user has not toggled the caption tune\r\n * True when user has toggled the caption tune\r\n * False when user has toggled the caption tune\r\n */\r\n private isCaptionEnabled: boolean | null = null;\r\n\r\n /**\r\n * @param tool - tool properties got from editor.js\r\n * @param tool.data - previously saved data\r\n * @param tool.config - user config for Tool\r\n * @param tool.api - Editor.js API\r\n * @param tool.readOnly - read-only mode flag\r\n * @param tool.block - current Block API\r\n */\r\n constructor({ data, config, api, readOnly, block }: ImageToolConstructorOptions) {\r\n this.api = api;\r\n this.block = block;\r\n this.userStore=config?.userStore;\r\n \r\n /**\r\n * Tool's initial config\r\n */\r\n this.config = {\r\n endpoints: config.endpoints,\r\n additionalRequestData: config.additionalRequestData,\r\n additionalRequestHeaders: config.additionalRequestHeaders,\r\n field: config.field,\r\n types: config.types,\r\n captionPlaceholder: this.api.i18n.t(config.captionPlaceholder ?? 'Caption'),\r\n buttonContent: config.buttonContent,\r\n uploader: config.uploader,\r\n actions: config.actions,\r\n features: config.features || {},\r\n userStore: config.userStore,\r\n };\r\n \r\n\r\n /**\r\n * Module for file uploading\r\n */\r\n this.uploader = new Uploader({\r\n config: this.config,\r\n onUpload: (response: UploadResponseFormat) => this.onUpload(response),\r\n onError: (error: string) => this.uploadingFailed(error),\r\n });\r\n\r\n /**\r\n * Module for working with UI\r\n */\r\n this.ui = new Ui({\r\n api,\r\n config: this.config,\r\n onSelectFile: () => {\r\n this.uploader.uploadSelectedFile({\r\n onPreview: (src: string) => {\r\n this.ui.showPreloader(src);\r\n },\r\n noSelectedFile:()=>{\r\n this.noSelectedFile();\r\n }\r\n });\r\n },\r\n readOnly,\r\n });\r\n\r\n /**\r\n * Set saved state\r\n */\r\n this._data = {\r\n caption: '',\r\n withBorder: false,\r\n withBackground: false,\r\n stretched: false,\r\n file: {\r\n url: '',\r\n },\r\n };\r\n this.data = data;\r\n }\r\n\r\n private noSelectedFile(): void {\r\n this.api.blocks.delete(this.api.blocks.getCurrentBlockIndex());\r\n }\r\n private deleteCurrentBlock() {\r\n this.api.blocks.delete(this.api.blocks.getCurrentBlockIndex());\r\n }\r\n /**\r\n * Notify core that read-only mode is supported\r\n */\r\n public static get isReadOnlySupported(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n */\r\n public static get toolbox(): ToolboxConfig {\r\n return {\r\n icon: IconPicture,\r\n title: 'Image',\r\n };\r\n }\r\n\r\n /**\r\n * Available image tools\r\n */\r\n public static get tunes(): Array<ActionConfig> {\r\n return [\r\n {\r\n name: 'withBorder',\r\n icon: IconAddBorder,\r\n title: 'With border',\r\n toggle: true,\r\n },\r\n {\r\n name: 'stretched',\r\n icon: IconStretch,\r\n title: 'Stretch image',\r\n toggle: true,\r\n },\r\n {\r\n name: 'withBackground',\r\n icon: IconAddBackground,\r\n title: 'With background',\r\n toggle: true,\r\n },\r\n ];\r\n }\r\n\r\n /**\r\n * Renders Block content\r\n */\r\n public render(): HTMLDivElement {\r\n if (this.config.features?.caption === true || this.config.features?.caption === undefined || (this.config.features?.caption === 'optional' && this.data.caption)) {\r\n this.isCaptionEnabled = true;\r\n this.ui.applyTune('caption', true);\r\n }\r\n\r\n return this.ui.render() as HTMLDivElement;\r\n }\r\n\r\n /**\r\n * Validate data: check if Image exists\r\n * @param savedData — data received after saving\r\n * @returns false if saved data is not correct, otherwise true\r\n */\r\n public validate(savedData: ImageToolData): boolean {\r\n return !!savedData.file.url;\r\n }\r\n\r\n /**\r\n * Return Block data\r\n */\r\n public save(): ImageToolData {\r\n const caption = this.ui.nodes.caption;\r\n\r\n this._data.caption = caption.innerHTML;\r\n\r\n return this.data;\r\n }\r\n\r\n /**\r\n * Returns configuration for block tunes: add background, add border, stretch image\r\n * @returns TunesMenuConfig\r\n */\r\n public renderSettings(): TunesMenuConfig {\r\n // Merge default tunes with the ones that might be added by user\r\n // @see https://github.com/editor-js/image/pull/49\r\n const tunes = ImageTool.tunes.concat(this.config.actions || []);\r\n const featureTuneMap: Record<string, string> = {\r\n border: 'withBorder',\r\n background: 'withBackground',\r\n stretch: 'stretched',\r\n caption: 'caption',\r\n };\r\n\r\n if (this.config.features?.caption === 'optional') {\r\n tunes.push({\r\n name: 'caption',\r\n icon: IconText,\r\n title: 'With caption',\r\n toggle: true,\r\n });\r\n }\r\n\r\n const availableTunes = tunes.filter((tune) => {\r\n const featureKey = Object.keys(featureTuneMap).find(key => featureTuneMap[key] === tune.name);\r\n\r\n if (featureKey === 'caption') {\r\n return this.config.features?.caption !== false;\r\n }\r\n\r\n return featureKey == null || this.config.features?.[featureKey as keyof FeaturesConfig] !== false;\r\n });\r\n\r\n /**\r\n * Check if the tune is active\r\n * @param tune - tune to check\r\n */\r\n const isActive = (tune: ActionConfig): boolean => {\r\n let currentState = this.data[tune.name as keyof ImageToolData] as boolean;\r\n\r\n if (tune.name === 'caption') {\r\n currentState = this.isCaptionEnabled ?? currentState;\r\n }\r\n\r\n return currentState;\r\n };\r\n\r\n return availableTunes.map(tune => ({\r\n icon: tune.icon,\r\n label: this.api.i18n.t(tune.title),\r\n name: tune.name,\r\n toggle: tune.toggle,\r\n isActive: isActive(tune),\r\n onActivate: () => {\r\n /** If it'a user defined tune, execute it's callback stored in action property */\r\n if (typeof tune.action === 'function') {\r\n tune.action(tune.name);\r\n\r\n return;\r\n }\r\n let newState = !isActive(tune);\r\n\r\n /**\r\n * For the caption tune, we can't rely on the this._data\r\n * because it can be manualy toggled by user\r\n */\r\n if (tune.name === 'caption') {\r\n this.isCaptionEnabled = !(this.isCaptionEnabled ?? false);\r\n newState = this.isCaptionEnabled;\r\n }\r\n\r\n this.tuneToggled(tune.name as keyof ImageToolData, newState);\r\n },\r\n }));\r\n }\r\n\r\n /**\r\n * Fires after clicks on the Toolbox Image Icon\r\n * Initiates click on the Select File button\r\n */\r\n public appendCallback(): void {\r\n this.ui.nodes.fileButton.click();\r\n }\r\n\r\n /**\r\n * Specify paste substitutes\r\n * @see {@link https://github.com/codex-team/editor.js/blob/master/docs/tools.md#paste-handling}\r\n */\r\n public static get pasteConfig(): PasteConfig {\r\n return {\r\n /**\r\n * Paste HTML into Editor\r\n */\r\n tags: [\r\n {\r\n img: { src: true },\r\n },\r\n ],\r\n /**\r\n * Paste URL of image into the Editor\r\n */\r\n // patterns: {\r\n // image: /https?:\\/\\/\\S+\\.(gif|jpe?g|png|webp)(\\?[a-z0-9=]*)?$/i,\r\n // },\r\n\r\n /**\r\n * Drag n drop file from into the Editor\r\n */\r\n files: {\r\n mimeTypes: ['image/*'],\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Specify paste handlers\r\n * @see {@link https://github.com/codex-team/editor.js/blob/master/docs/tools.md#paste-handling}\r\n * @param event - editor.js custom paste event\r\n * {@link https://github.com/codex-team/editor.js/blob/master/types/tools/paste-events.d.ts}\r\n */\r\n public async onPaste(event: PasteEvent): Promise<void> {\r\n switch (event.type) {\r\n case 'tag': {\r\n const image = (event.detail as HTMLPasteEventDetailExtended).data;\r\n\r\n /** Images from PDF */\r\n if (/^blob:/.test(image.src)) {\r\n const response = await fetch(image.src);\r\n\r\n const file = await response.blob();\r\n\r\n this.uploadFile(file);\r\n break;\r\n }\r\n\r\n this.uploadUrl(image.src);\r\n break;\r\n }\r\n // case 'pattern': {\r\n // const url = (event.detail as PatternPasteEventDetail).data;\r\n\r\n // this.uploadUrl(url);\r\n // break;\r\n // }\r\n case 'file': {\r\n const file = (event.detail as FilePasteEventDetail).file;\r\n\r\n this.uploadFile(file);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Private methods\r\n */\r\n\r\n /**\r\n * Stores all Tool's data\r\n * @param data - data in Image Tool format\r\n */\r\n private set data(data: ImageToolData) {\r\n this.image = data.file;\r\n\r\n this._data.caption = data.caption || '';\r\n this.ui.fillCaption(this._data.caption);\r\n\r\n ImageTool.tunes.forEach(({ name: tune }) => {\r\n const value = typeof data[tune as keyof ImageToolData] !== 'undefined' ? data[tune as keyof ImageToolData] === true || data[tune as keyof ImageToolData] === 'true' : false;\r\n\r\n this.setTune(tune as keyof ImageToolData, value);\r\n });\r\n\r\n if (data.caption) {\r\n this.setTune('caption', true);\r\n } else if (this.config.features?.caption === true) {\r\n this.setTune('caption', true);\r\n }\r\n }\r\n\r\n /**\r\n * Return Tool data\r\n */\r\n private get data(): ImageToolData {\r\n return this._data;\r\n }\r\n\r\n /**\r\n * Set new image file\r\n * @param file - uploaded file data\r\n */\r\n private set image(file: ImageSetterParam | undefined) {\r\n this._data.file = file || { url: '' };\r\n\r\n if (file && file.url) {\r\n this.ui.fillImage(file.url);\r\n }\r\n }\r\n\r\n /**\r\n * File uploading callback\r\n * @param response - uploading server response\r\n */\r\n private onUpload(response: UploadResponseFormat): void {\r\n if (response.success && Boolean(response.file)) {\r\n this.image = response.file;\r\n } else {\r\n this.uploadingFailed('incorrect response: ' + JSON.stringify(response));\r\n }\r\n }\r\n\r\n /**\r\n * Handle uploader errors\r\n * @param errorText - uploading error info\r\n */\r\n private uploadingFailed(errorText: string): void {\r\n console.log('Image Tool: uploading failed because of', errorText);\r\n let errorMessage = this.api.i18n.t('Couldn’t upload image. Please try another.');\r\n if (errorText) {\r\n errorMessage = this.api.i18n.t(errorText);\r\n }\r\n this.api.notifier.show({\r\n message: errorMessage,\r\n style: 'error',\r\n });\r\n this.ui.hidePreloader();\r\n this.deleteCurrentBlock();\r\n }\r\n\r\n /**\r\n * Callback fired when Block Tune is activated\r\n * @param tuneName - tune that has been clicked\r\n * @param state - new state\r\n */\r\n private tuneToggled(tuneName: keyof ImageToolData, state: boolean): void {\r\n if (tuneName === 'caption') {\r\n this.ui.applyTune(tuneName, state);\r\n\r\n if (state == false) {\r\n this._data.caption = '';\r\n this.ui.fillCaption('');\r\n }\r\n } else {\r\n /**\r\n * Inverse tune state\r\n */\r\n this.setTune(tuneName, state);\r\n }\r\n }\r\n\r\n /**\r\n * Set one tune\r\n * @param tuneName - {@link Tunes.tunes}\r\n * @param value - tune state\r\n */\r\n private setTune(tuneName: keyof ImageToolData, value: boolean): void {\r\n (this._data[tuneName] as boolean) = value;\r\n\r\n this.ui.applyTune(tuneName, value);\r\n if (tuneName === 'stretched') {\r\n /**\r\n * Wait until the API is ready\r\n */\r\n Promise.resolve().then(() => {\r\n this.block.stretched = value;\r\n })\r\n .catch((err) => {\r\n console.error(err);\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Show preloader and upload image file\r\n * @param file - file that is currently uploading (from paste)\r\n */\r\n private uploadFile(file: Blob): void {\r\n this.uploader.uploadByFile(file, {\r\n onPreview: (src: string) => {\r\n this.ui.showPreloader(src);\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Show preloader and upload image by target url\r\n * @param url - url pasted\r\n */\r\n private uploadUrl(url: string): void {\r\n this.ui.showPreloader(url);\r\n this.uploader.uploadByUrl(url);\r\n }\r\n}\r\n","\r\n//import Cropper from 'cropperjs';\r\n//import 'cropperjs/dist/cropper.css';\r\nimport './index.css';\r\nimport type { BlockTune, API, BlockAPI } from '@ebl-vue/editorjs/types'\r\n\r\n\r\nexport interface TuneSetting {\r\n name: string;\r\n icon: string;\r\n label: string;\r\n group: string;\r\n}\r\n\r\nexport interface ImageToolTuneData {\r\n floatLeft: boolean;\r\n floatRight: boolean;\r\n center: boolean;\r\n sizeSmall: boolean;\r\n sizeMiddle: boolean;\r\n sizeLarge: boolean;\r\n resize: boolean;\r\n resizeSize: number;\r\n crop: boolean;\r\n cropperFrameHeight: number;\r\n cropperFrameWidth: number;\r\n cropperFrameLeft: number;\r\n cropperFrameTop: number;\r\n cropperImageHeight: number;\r\n cropperImageWidth: number;\r\n cropperInterface?: any//Cropper;\r\n}\r\n\r\nexport interface ImageToolTuneConfig {\r\n resize: boolean;\r\n crop: boolean;\r\n}\r\n\r\nexport interface CustomStyles {\r\n settingsButton: string;\r\n settingsButtonActive: string;\r\n settingsButtonModifier?: string;\r\n settingsButtonModifierActive?: string;\r\n}\r\n\r\nexport type ImageToolTuneConstructor = {\r\n api: API;\r\n data: Partial<ImageToolTuneData>;\r\n config?: ImageToolTuneConfig;\r\n block: BlockAPI;\r\n};\r\n\r\nexport default class ImageToolTune implements BlockTune {\r\n private settings: TuneSetting[];\r\n private api: API;\r\n private block: BlockAPI;\r\n private data: ImageToolTuneData;\r\n private wrapper: HTMLElement | undefined;\r\n private buttons: HTMLElement[];\r\n private styles: CustomStyles;\r\n\r\n constructor({ api, data, config, block }: ImageToolTuneConstructor) {\r\n this.settings = [\r\n // {\r\n // name: 'resize',\r\n // icon: '<svg stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" viewBox=\"0 0 512 512\" height=\"1em\" width=\"1em\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M29 30l1 90h36V66h26V30H29zm99 0v36h72V30h-72zm108 0v36h72V30h-72zm108 0v36h72V30h-72zm102 0v78h36V30h-36zm-206 80v36h100.543l-118 118H30v218h218V289.457l118-118V272h36V110H240zm206 34v72h36v-72h-36zM30 156v72h36v-72H30zm416 96v72h36v-72h-36zm0 108v72h36v-72h-36zm-166 86v36h72v-36h-72zm108 0v36h72v-36h-72z\"></path></svg>',\r\n // label: '',\r\n // group: 'size',\r\n // },\r\n // {\r\n // name: 'crop',\r\n // icon: '<svg stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" viewBox=\"0 0 24 24\" height=\"1em\" width=\"1em\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M21 15h2v2h-2v-2zm0-4h2v2h-2v-2zm2 8h-2v2c1 0 2-1 2-2zM13 3h2v2h-2V3zm8 4h2v2h-2V7zm0-4v2h2c0-1-1-2-2-2zM1 7h2v2H1V7zm16-4h2v2h-2V3zm0 16h2v2h-2v-2zM3 3C2 3 1 4 1 5h2V3zm6 0h2v2H9V3zM5 3h2v2H5V3zm-4 8v8c0 1.1.9 2 2 2h12V11H1zm2 8l2.5-3.21 1.79 2.15 2.5-3.22L13 19H3z\"></path></svg>',\r\n // label: '',\r\n // group: 'size',\r\n // },\r\n ];\r\n\r\n this.api = api;\r\n this.block = block;\r\n this.data = {\r\n floatLeft: data?.floatLeft ?? false,\r\n floatRight: data?.floatRight ?? false,\r\n center: data?.center ?? false,\r\n sizeSmall: data?.sizeSmall ?? false,\r\n sizeMiddle: data?.sizeMiddle ?? false,\r\n sizeLarge: data?.sizeLarge ?? false,\r\n resize: data?.resize ?? config?.resize ?? false,\r\n resizeSize: data?.resizeSize ?? 0,\r\n crop: data?.crop ?? config?.crop ?? false,\r\n cropperFrameHeight: data?.cropperFrameHeight ?? 0,\r\n cropperFrameWidth: data?.cropperFrameWidth ?? 0,\r\n cropperFrameLeft: data?.cropperFrameLeft ?? 0,\r\n cropperFrameTop: data?.cropperFrameTop ?? 0,\r\n cropperImageHeight: data?.cropperImageHeight ?? 0,\r\n cropperImageWidth: data?.cropperImageWidth ?? 0,\r\n cropperInterface: undefined,\r\n };\r\n this.wrapper = undefined;\r\n this.buttons = [];\r\n this.styles = {\r\n settingsButton: 'cdx-settings-button',\r\n settingsButtonActive: 'cdx-settings-button--active',\r\n settingsButtonModifier: '',\r\n settingsButtonModifierActive: '',\r\n };\r\n }\r\n\r\n static get isTune(): boolean {\r\n return true;\r\n }\r\n\r\n static get sanitize(): Record<string, object> {\r\n return {\r\n floatLeft: {},\r\n floatRight: {},\r\n center: {},\r\n sizeSmall: {},\r\n sizeMiddle: {},\r\n sizeLarge: {},\r\n resize: {},\r\n resizeSize: {},\r\n crop: {},\r\n cropperFrameHeight: {},\r\n cropperFrameWidth: {},\r\n cropperFrameLeft: {},\r\n cropperFrameTop: {},\r\n cropperImageHeight: {},\r\n cropperImageWidth: {},\r\n cropperInterface: {},\r\n };\r\n }\r\n\r\n /**\r\n * CSS classes\r\n * @return {object}\r\n * @constructor\r\n * @property {string} CSS.wrapper - wrapper for buttons\r\n * @property {string} CSS.button - button\r\n * @property {string} CSS.buttonActive - active button\r\n * @property {string} CSS.buttonModifier - button with modifier\r\n * @property {string} CSS.buttonModifierActive - active button with modifier\r\n */\r\n get CSS(): Record<string, string> {\r\n return {\r\n wrapper: 'cdx-image-tool-tune',\r\n button: this.styles.settingsButton,\r\n buttonActive: this.styles.settingsButtonActive,\r\n buttonModifier: this.styles.settingsButtonModifier || '',\r\n buttonModifierActive: this.styles.settingsButtonModifierActive || '',\r\n isFloatLeft: 'cdx-image-tool-tune--floatLeft',\r\n isFloatRight: 'cdx-image-tool-tune--floatRight',\r\n isCenter: 'cdx-image-tool-tune--center',\r\n isSizeSmall: 'cdx-image-tool-tune--sizeSmall',\r\n isSizeMiddle: 'cdx-image-tool-tune--sizeMiddle',\r\n isSizeLarge: 'cdx-image-tool-tune--sizeLarge',\r\n isResize: 'cdx-image-tool-tune--resize',\r\n isCrop: 'cdx-image-tool-tune--crop',\r\n };\r\n }\r\n\r\n /**\r\n *\r\n * @return {HTMLElement}\r\n * @public\r\n * @readonly\r\n * @property {HTMLElement} wrapper - tune buttons wrapper\r\n */\r\n get view(): HTMLElement {\r\n if (!this.wrapper) {\r\n this.wrapper = this.createView();\r\n }\r\n\r\n return this.wrapper;\r\n }\r\n\r\n /**\r\n * Clicks to one of the tunes\r\n * @param {MouseEvent} e - click\r\n * @param {HTMLElement} tune - clicked tune button\r\n * @private\r\n * @return {void}\r\n * */\r\n tuneClicked(e: MouseEvent, tune: HTMLElement): void {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n const tuneName = tune.dataset.tune || '';\r\n const tuneGroup = this.settings.find(t => t.name === tuneName)?.group;\r\n\r\n this.buttons.forEach(button => {\r\n //if is the same group\r\n if (\r\n this.settings.find(t => t.name === button.dataset.tune)?.group ===\r\n tuneGroup\r\n ) {\r\n if (button !== tune) {\r\n button.classList.remove(this.CSS.buttonActive);\r\n }\r\n }\r\n });\r\n\r\n tune.classList.toggle(this.CSS.buttonActive);\r\n this.setTune(tuneName);\r\n }\r\n\r\n /**\r\n * Styles the image with a tune\r\n * @param {string} tune - tune name\r\n * @private\r\n * @return {void}\r\n * */\r\n setTune(tune: string): void {\r\n switch (tune) {\r\n case 'floatLeft':\r\n this.data.floatLeft = !this.data.floatLeft;\r\n this.data.floatRight = false;\r\n this.data.center = false;\r\n break;\r\n case 'floatRight':\r\n this.data.floatLeft = false;\r\n this.data.floatRight = !this.data.floatRight;\r\n this.data.center = false;\r\n break;\r\n case 'center':\r\n this.data.center = !this.data.center;\r\n this.data.floatLeft = false;\r\n this.data.floatRight = false;\r\n break;\r\n case 'sizeSmall':\r\n this.data.sizeSmall = !this.data.sizeSmall;\r\n this.data.sizeMiddle = false;\r\n this.data.sizeLarge = false;\r\n this.data.resize = false;\r\n this.data.crop = false;\r\n break;\r\n case 'sizeMiddle':\r\n this.data.sizeSmall = false;\r\n this.data.sizeMiddle = !this.data.sizeMiddle;\r\n this.data.sizeLarge = false;\r\n this.data.resize = false;\r\n this.data.crop = false;\r\n break;\r\n case 'sizeLarge':\r\n this.data.sizeSmall = false;\r\n this.data.sizeMiddle = false;\r\n this.data.sizeLarge = !this.data.sizeLarge;\r\n this.data.resize = false;\r\n this.data.crop = false;\r\n break;\r\n case 'resize':\r\n this.data.sizeSmall = false;\r\n this.data.sizeMiddle = false;\r\n this.data.sizeLarge = false;\r\n this.data.resize = !this.data.resize;\r\n this.data.crop = false;\r\n break;\r\n case 'crop':\r\n this.data.crop = !this.data.crop;\r\n this.data.sizeSmall = false;\r\n this.data.sizeMiddle = false;\r\n this.data.sizeLarge = false;\r\n this.data.resize = false;\r\n this.data.resizeSize = 0;\r\n break;\r\n default:\r\n this.data.floatLeft = false;\r\n this.data.floatRight = false;\r\n this.data.sizeSmall = false;\r\n this.data.sizeMiddle = false;\r\n this.data.sizeLarge = false;\r\n this.data.resize = false;\r\n this.data.crop = false;\r\n break;\r\n }\r\n\r\n if (!this.data.resize) {\r\n this.data.resizeSize = 0;\r\n }\r\n\r\n if (!this.data.crop) {\r\n this.data.cropperFrameHeight = 0;\r\n this.data.cropperFrameWidth = 0;\r\n this.data.cropperFrameLeft = 0;\r\n this.data.cropperFrameTop = 0;\r\n this.data.cropperImageHeight = 0;\r\n this.data.cropperImageWidth = 0;\r\n }\r\n\r\n const blockContent = this.block.holder.querySelector(\r\n '.ce-block__content',\r\n ) as HTMLElement;\r\n this.apply(blockContent);\r\n this.block.dispatchChange();\r\n }\r\n\r\n /**\r\n * Append class to block by tune data\r\n * @param {HTMLElement} blockContent - wrapper for block content\r\n * @public\r\n * @return {void}\r\n * */\r\n apply(blockContent: HTMLElement): void {\r\n if (this.data.floatLeft) {\r\n blockContent.classList.add(this.CSS.isFloatLeft);\r\n } else {\r\n blockContent.classList.remove(this.CSS.isFloatLeft);\r\n }\r\n\r\n if (this.data.floatRight) {\r\n blockContent.classList.add(this.CSS.isFloatRight);\r\n } else {\r\n blockContent.classList.remove(this.CSS.isFloatRight);\r\n }\r\n\r\n if (this.data.center) {\r\n blockContent.classList.add(this.CSS.isCenter);\r\n } else {\r\n blockContent.classList.remove(this.CSS.isCenter);\r\n }\r\n\r\n if (this.data.sizeSmall) {\r\n blockContent.classList.add(this.CSS.isSizeSmall);\r\n } else {\r\n blockContent.classList.remove(this.CSS.isSizeSmall);\r\n }\r\n\r\n if (this.data.sizeMiddle) {\r\n blockContent.classList.add(this.CSS.isSizeMiddle);\r\n } else {\r\n blockContent.classList.remove(this.CSS.isSizeMiddle);\r\n }\r\n\r\n if (this.data.sizeLarge) {\r\n blockContent.classList.add(this.CSS.isSizeLarge);\r\n } else {\r\n blockContent.classList.remove(this.CSS.isSizeLarge);\r\n }\r\n\r\n if (this.data.resize) {\r\n blockContent.classList.add(this.CSS.isResize);\r\n\r\n if (this.data.resizeSize > 0) {\r\n const cdxBlock = blockContent.getElementsByClassName(\r\n 'cdx-block',\r\n )[0] as HTMLElement;\r\n cdxBlock.style.width = this.data.resizeSize + 'px';\r\n }\r\n\r\n this.resize(blockContent);\r\n } else {\r\n blockContent.classList.remove(this.CSS.isResize);\r\n this.unresize(blockContent);\r\n }\r\n\r\n if (this.data.crop) {\r\n blockContent.classList.add(this.CSS.isCrop);\r\n\r\n this.crop(blockContent);\r\n if (this.data.cropperFrameHeight > 0 && this.data.cropperFrameWidth > 0) {\r\n this.applyCrop(blockContent);\r\n }\r\n } else {\r\n blockContent.classList.remove(this.CSS.isCrop);\r\n this.uncrop(blockContent);\r\n }\r\n }\r\n\r\n /**\r\n * Add crop handles to image\r\n * @param {HTMLElement} blockContent - wrapper for block content\r\n * @public\r\n * @return {void}\r\n */\r\n crop(blockContent: HTMLElement): void {\r\n //add append crop button to image-tool__image\r\n //If editor is readOnly, do not add crop button\r\n if (this.api.readOnly.isEnabled) return;\r\n\r\n const image = blockContent.getElementsByClassName(\r\n 'image-tool__image',\r\n )[0] as HTMLElement;\r\n const cropBtn = document.createElement('div');\r\n cropBtn.classList.add('crop-btn', 'btn-crop-action');\r\n cropBtn.innerHTML = this.api.i18n.t('Crop');\r\n\r\n cropBtn.addEventListener('click', () => {\r\n //remove crop button\r\n image.removeChild(cropBtn);\r\n this.appendCrop(blockContent);\r\n });\r\n\r\n image.appendChild(cropBtn);\r\n }\r\n\r\n appendCrop(blockContent: HTMLElement): void {\r\n if (this.api.readOnly.isEnabled) return;\r\n\r\n this.uncrop(blockContent);\r\n const cdxBlock = blockContent.getElementsByClassName(\r\n 'cdx-block',\r\n )[0] as HTMLElement;\r\n const image = cdxBlock.getElementsByTagName('img')[0] as HTMLImageElement;\r\n cdxBlock.classList.add('isCropping');\r\n this.data.cropperInterface = new Cropper(image);\r\n\r\n //append save crop button\r\n const cropSaveBtn = document.createElement('div');\r\n cropSaveBtn.classList.add('crop-save', 'btn-crop-action');\r\n cropSaveBtn.innerHTML = this.api.i18n.t('Apply');\r\n\r\n cropSaveBtn.addEventListener('click', () => {\r\n if (this.data.cropperInterface) {\r\n this.data.cropperFrameHeight =\r\n this.data.cropperInterface.getCropBoxData().height;\r\n this.data.cropperFrameWidth =\r\n this.data.cropperInterface.getCropBoxData().width;\r\n this.data.cropperFrameLeft =\r\n this.data.cropperInterface.getCanvasData().left -\r\n this.data.cropperInterface.getCropBoxData().left;\r\n this.data.cropperFrameTop =\r\n this.data.cropperInterface.getCanvasData().top -\r\n this.data.cropperInterface.getCropBoxData().top;\r\n this.data.cropperImageHeight =\r\n this.data.cropperInterface.getImageData().height;\r\n this.data.cropperImageWidth =\r\n this.data.cropperInterface.getImageData().width;\r\n }\r\n this.applyCrop(blockContent);\r\n });\r\n\r\n const imageToolImage = blockContent.getElementsByClassName(\r\n 'image-tool__image',\r\n )[0] as HTMLElement;\r\n imageToolImage.appendChild(cropSaveBtn);\r\n\r\n //add temporary style to block content so that it comes in front of every other block\r\n blockContent.classList.add('isCropping');\r\n }\r\n\r\n applyCrop(blockContent: HTMLElement): void {\r\n //apply data to image and remove cropper interface and save button, add crop button\r\n const blockEl = blockContent.getElementsByClassName(\r\n 'cdx-block',\r\n )[0] as HTMLElement;\r\n if (blockEl) {\r\n blockEl.style.minWidth = this.data.cropperFrameWidth + 'px';\r\n blockEl.style.maxWidth = this.data.cropperFrameWidth + 'px';\r\n\r\n const image = blockEl.getElementsByTagName('img')[0] as HTMLImageElement;\r\n image.style.width = this.data.cropperImageWidth + 'px';\r\n image.style.height = this.data.cropperImageHeight + 'px';\r\n\r\n const blockImg = blockContent.getElementsByClassName(\r\n 'image-tool__image',\r\n )[0] as HTMLElement;\r\n blockImg.style.width = this.data.cropperFrameWidth + 'px';\r\n blockImg.style.height = this.data.cropperFrameHeight + 'px';\r\n\r\n const imageEl = blockImg.getElementsByTagName(\r\n 'img',\r\n )[0] as HTMLImageElement;\r\n if (imageEl) {\r\n imageEl.style.left = this.data.cropperFrameLeft + 'px';\r\n imageEl.style.top = this.data.cropperFrameTop + 'px';\r\n imageEl.classList.add('isCropped');\r\n }\r\n\r\n blockEl.classList.remove('isCropping');\r\n\r\n const cropSaveBtn = blockContent.getElementsByClassName(\r\n 'btn-crop-action',\r\n )[0] as HTMLElement;\r\n if (cropSaveBtn) {\r\n blockImg.removeChild(cropSaveBtn);\r\n }\r\n }\r\n\r\n //remove cropper interface\r\n if (this.data.cropperInterface) {\r\n this.data.cropperInterface.destroy();\r\n this.data.cropperInterface = undefined;\r\n }\r\n\r\n //add crop button\r\n if (this.api.readOnly.isEnabled) return;\r\n const cropBtn = document.createElement('div');\r\n cropBtn.classList.add('crop-btn', 'btn-crop-action');\r\n cropBtn.innerHTML = this.api.i18n.t('Crop');\r\n\r\n const imageToolImage = blockContent.getElementsByClassName(\r\n 'image-tool__image',\r\n )[0] as HTMLElement;\r\n if (imageToolImage) {\r\n cropBtn.addEventListener('click', () => {\r\n //remove crop button\r\n imageToolImage.removeChild(cropBtn);\r\n this.appendCrop(blockContent);\r\n });\r\n\r\n imageToolImage.appendChild(cropBtn);\r\n }\r\n\r\n blockContent.classList.remove('isCropping');\r\n this.block.dispatchChange();\r\n }\r\n\r\n uncrop(blockContent: HTMLElement): void {\r\n if (this.api.readOnly.isEnabled) return;\r\n\r\n const imageEl = blockContent.getElementsByClassName(\r\n 'image-tool__image',\r\n )[0] as HTMLElement;\r\n\r\n //remove crop and save button\r\n const cropSaveBtn = blockContent.getElementsByClassName(\r\n 'btn-crop-action',\r\n )[0] as HTMLElement;\r\n if (cropSaveBtn && imageEl) {\r\n imageEl.removeChild(cropSaveBtn);\r\n }\r\n\r\n //remove crop button\r\n const cropBtn = blockContent.getElementsByClassName(\r\n 'btn-crop-action',\r\n )[0] as HTMLElement;\r\n if (cropBtn && imageEl) {\r\n imageEl.removeChild(cropBtn);\r\n }\r\n\r\n //remove isCropped class\r\n const blockEl = blockContent.getElementsByClassName(\r\n 'cdx-block',\r\n )[0] as HTMLElement;\r\n if (blockEl) {\r\n const image = blockEl.getElementsByTagName('img')[0] as HTMLImageElement;\r\n if (image) image.classList.remove('isCropped');\r\n\r\n //remove isCropping class\r\n blockEl.classList.remove('isCropping');\r\n\r\n //remove min and max width\r\n blockEl.style.minWidth = '';\r\n blockEl.style.maxWidth = '';\r\n }\r\n\r\n if (imageEl) {\r\n //remove image width and height\r\n imageEl.style.width = '';\r\n imageEl.style.height = '';\r\n\r\n //remove image left and top\r\n const image = imageEl.getElementsByTagName('img')[0] as HTMLImageElement;\r\n if (image) {\r\n image.style.left = '';\r\n image.style.top = '';\r\n\r\n //remove image width and height\r\n image.style.width = '';\r\n image.style.height = '';\r\n }\r\n }\r\n\r\n blockContent.classList.remove('isCropping');\r\n\r\n //remove cropper interface\r\n if (this.data.cropperInterface) {\r\n this.data.cropperInterface.destroy();\r\n this.data.cropperInterface = undefined;\r\n }\r\n\r\n //remove crop data\r\n this.data.cropperFrameHeight = 0;\r\n this.data.cropperFrameWidth = 0;\r\n this.data.cropperFrameLeft = 0;\r\n this.data.cropperFrameTop = 0;\r\n this.data.cropperImageHeight = 0;\r\n this.data.cropperImageWidth = 0;\r\n }\r\n\r\n /**\r\n * Add resize handles to block\r\n * @param {HTMLElement} blockContent - wrapper for block content\r\n * @public\r\n * @return {void}\r\n * */\r\n resize(blockContent: HTMLElement): void {\r\n if (this.api.readOnly.isEnabled) return;\r\n const resizable = document.createElement('div');\r\n resizable.classList.add('resizable');\r\n\r\n const resizers = document.createElement('div');\r\n resizers.classList.add('resizers');\r\n\r\n const resizerTopRight = document.createElement('div');\r\n resizerTopRight.classList.add('resizer', 'top-right');\r\n resizerTopRight.addEventListener('mousedown', e => {\r\n this.resizeClick(\r\n blockContent.getElementsByClassName('cdx-block')[0] as HTMLElement,\r\n resizerTopRight,\r\n e,\r\n );\r\n });\r\n\r\n const resizerBottomRight = document.createElement('div');\r\n resizerBottomRight.classList.add('resizer', 'bottom-right');\r\n resizerBottomRight.addEventListener('mousedown', e => {\r\n this.resizeClick(\r\n blockContent.getElementsByClassName('cdx-block')[0] as HTMLElement,\r\n resizerBottomRight,\r\n e,\r\n );\r\n });\r\n\r\n resizers.appendChild(resizerTopRight);\r\n resizers.appendChild(resizerBottomRight);\r\n resizable.appendChild(resizers);\r\n blockContent.getElementsByClassName('cdx-block')[0].appendChild(resizable);\r\n }\r\n\r\n /**\r\n * click event to resize handles\r\n * preserve aspect ratio\r\n * prevent block from moving when dragging resize handles\r\n * max size = 100%\r\n * min size = 50px\r\n * @param {HTMLElement} blockContent - wrapper for block content\r\n * @param {HTMLElement} handle - resize handle\r\n * @param {MouseEvent} e - mouse event\r\n * @public\r\n * @return {void}\r\n * */\r\n resizeClick(blockContent: HTMLElement, _: HTMLElement, e: MouseEvent): void {\r\n const maxWidth =\r\n document.getElementsByClassName('codex-editor')[0].clientWidth;\r\n\r\n let startX = 0;\r\n let startWidth = 0;\r\n\r\n const mouseMoveHandler = (e: MouseEvent) => {\r\n const dx = e.clientX - startX;\r\n const newWidth = startWidth + dx;\r\n\r\n if (newWidth > 50 && newWidth < maxWidth) {\r\n (\r\n blockContent as HTMLElement & { style: CSSStyleDeclaration }\r\n ).style.width = newWidth + 'px';\r\n }\r\n };\r\n\r\n const mouseUpHandler = () => {\r\n const blockWidth = parseInt(\r\n window.getComputedStyle(blockContent).width,\r\n 10,\r\n );\r\n\r\n if (blockWidth > 0) {\r\n this.data.resizeSize = blockWidth;\r\n }\r\n\r\n document.removeEventListener('mousemove', mouseMoveHandler);\r\n document.removeEventListener('mouseup', mouseUpHandler);\r\n\r\n this.block.dispatchChange();\r\n };\r\n\r\n document.addEventListener('mousemove', mouseMoveHandler);\r\n document.addEventListener('mouseup', mouseUpHandler);\r\n\r\n startX = e.clientX;\r\n startWidth = parseInt(window.getComputedStyle(blockContent).width, 10);\r\n }\r\n\r\n /**\r\n * Remove resize handles from block\r\n * @param {HTMLElement} blockContent - wrapper for block content\r\n * @public\r\n * @return {void}\r\n */\r\n unresize(blockContent: HTMLElement): void {\r\n const unresizable = blockContent.getElementsByClassName(\r\n 'resizable',\r\n )[0] as HTMLElement;\r\n if (unresizable) {\r\n blockContent\r\n .getElementsByClassName('cdx-block')[0]\r\n .removeChild(unresizable);\r\n }\r\n\r\n const block: HTMLElement = blockContent.getElementsByClassName(\r\n 'cdx-block',\r\n )[0] as HTMLElement;\r\n block.style.width = 'auto';\r\n }\r\n\r\n /**\r\n * Remove tunes from block wrapper\r\n * @param {HTMLElement} blockContent - wrapper for block content\r\n * @public\r\n * @return {HTMLElement}\r\n */\r\n unwrap(blockContent: HTMLElement): HTMLElement {\r\n //remove tunes from block\r\n this.buttons.forEach(button => {\r\n button.classList.remove(this.CSS.buttonActive);\r\n });\r\n\r\n //remove isFloatLeft class\r\n blockContent.classList.remove(this.CSS.isFloatLeft);\r\n\r\n //remove isFloatRight class\r\n blockContent.classList.remove(this.CSS.isFloatRight);\r\n\r\n //remove isCenter class\r\n blockContent.classList.remove(this.CSS.isCenter);\r\n\r\n //remove isSizeSmall class\r\n blockContent.classList.remove(this.CSS.isSizeSmall);\r\n\r\n //remove isSizeMiddle class\r\n blockContent.classList.remove(this.CSS.isSizeMiddle);\r\n\r\n //remove isSizeLarge class\r\n blockContent.classList.remove(this.CSS.isSizeLarge);\r\n\r\n //remove isResize class\r\n blockContent.classList.remove(this.CSS.isResize);\r\n\r\n //remove isCrop class\r\n blockContent.classList.remove(this.CSS.isCrop);\r\n\r\n //remove isCropped class\r\n const cdxBlock = blockContent.getElementsByClassName(\r\n 'cdx-block',\r\n )[0] as HTMLElement;\r\n const img = cdxBlock.getElementsByTagName('img')[0] as HTMLImageElement;\r\n img.classList.remove('isCropped');\r\n\r\n //remove isCropping class\r\n cdxBlock.classList.remove('isCropping');\r\n\r\n //remove min and max width\r\n cdxBlock.style.minWidth = '';\r\n cdxBlock.style.maxWidth = '';\r\n\r\n //remove image width and height\r\n const imageToolImage = blockContent.getElementsByClassName(\r\n 'image-tool__image',\r\n )[0] as HTMLElement;\r\n imageToolImage.style.width = '';\r\n imageToolImage.style.height = '';\r\n\r\n //remove image left and top\r\n const image = imageToolImage.getElementsByTagName(\r\n 'img',\r\n )[0] as HTMLImageElement;\r\n image.style.left = '';\r\n image.style.top = '';\r\n\r\n //remove image width and height\r\n image.style.width = '';\r\n image.style.height = '';\r\n\r\n //remove resize handles\r\n this.unresize(blockContent);\r\n\r\n //remove crop handles\r\n this.uncrop(blockContent);\r\n\r\n //remove cropper interface\r\n if (this.data.cropperInterface) {\r\n this.data.cropperInterface.destroy();\r\n this.data.cropperInterface = undefined;\r\n }\r\n\r\n //remove crop data\r\n this.data.cropperFrameHeight = 0;\r\n this.data.cropperFrameWidth = 0;\r\n this.data.cropperFrameLeft = 0;\r\n this.data.cropperFrameTop = 0;\r\n this.data.cropperImageHeight = 0;\r\n this.data.cropperImageWidth = 0;\r\n\r\n return blockContent;\r\n }\r\n\r\n /**\r\n * Add tune to block data\r\n * @private\r\n * @return {ImageToolTuneData}\r\n * */\r\n save(): ImageToolTuneData {\r\n return this.data;\r\n }\r\n\r\n /**\r\n * Append tunes to block wrapper\r\n * @param {HTMLElement} blockContent - wrapper for block content\r\n * @public\r\n * @return {HTMLElement}\r\n * */\r\n wrap(blockContent: HTMLElement): HTMLElement {\r\n //createview if not exists\r\n if (!this.wrapper) {\r\n this.wrapper = this.createView();\r\n }\r\n\r\n this.apply(blockContent);\r\n return blockContent;\r\n }\r\n\r\n private tuneNameToI18nKey(tuneName: string): string {\r\n const translation: Record<string, string> = {\r\n crop: 'Crop',\r\n resize: 'Resize',\r\n };\r\n return translation[tuneName];\r\n }\r\n\r\n /**\r\n * Creates a view for tunes\r\n * @return {HTMLElement}\r\n * @private\r\n * */\r\n createView(): HTMLElement {\r\n this.buttons = this.settings.map(tune => {\r\n const el = document.createElement('div');\r\n const buttonIco = document.createElement('span');\r\n const buttonTxt = document.createElement('span');\r\n el.classList.add(this.CSS.button);\r\n buttonTxt.style.fontSize = '8px';\r\n buttonIco.innerHTML = tune.icon;\r\n buttonTxt.innerHTML = tune.label;\r\n el.appendChild(buttonIco);\r\n el.appendChild(buttonTxt);\r\n el.dataset.tune = tune.name;\r\n el.title = tune.label;\r\n\r\n el.addEventListener('click', e => this.tuneClicked(e, el));\r\n this.api.tooltip.onHover(\r\n el,\r\n this.api.i18n.t(this.tuneNameToI18nKey(tune.name)),\r\n );\r\n return el;\r\n });\r\n const wrapper = document.createElement('div');\r\n this.buttons.forEach(button => {\r\n wrapper.appendChild(button);\r\n });\r\n wrapper.classList.add(this.CSS.wrapper);\r\n return wrapper;\r\n }\r\n\r\n /**\r\n * Checks if tune is active\r\n * @param {string} tune - tune name\r\n * @return {boolean}\r\n * @private\r\n * */\r\n isTuneActive(tune: string): boolean {\r\n return !!this.data[tune as keyof ImageToolTuneData];\r\n }\r\n\r\n /**\r\n * Makes buttons with tunes\r\n * @return {HTMLElement}\r\n * @public\r\n * */\r\n render(): HTMLElement {\r\n //when editor is ready\r\n this.buttons.forEach(button => {\r\n const tuneName = button.dataset.tune || '';\r\n button.classList.toggle(\r\n this.CSS.buttonActive,\r\n this.isTuneActive(tuneName),\r\n );\r\n });\r\n\r\n return this.view;\r\n }\r\n\r\n /**\r\n * Destroys the plugin\r\n * @public\r\n * @return {void}\r\n * */\r\n destroy(): void {\r\n this.wrapper = undefined;\r\n this.buttons = [];\r\n }\r\n\r\n /**\r\n * Toggle tune\r\n * @param {string} tuneName - tune name\r\n * @private\r\n * @return {void}\r\n * */\r\n _toggleTune(tuneName: string): void {\r\n this.setTune(tuneName);\r\n }\r\n}\r\n","<template>\r\n <div class=\"ebl-editor\" id=\"holder\">\r\n <div class=\"ce-block__content ebl-editor-title-wrap\">\r\n <input type=\"text\" v-model=\"title\" placeholder=\"请输入标题\" class=\"ebl-editor-title-input\"></input>\r\n </div>\r\n <div class=\"ce-block__content ebl-editor-time-wrap\">\r\n <span class=\"ebl-editor-time\">最后修改时间:{{ lastUpdateTime }}</span>\r\n </div>\r\n <button @click=\"save\">保存</button> \r\n\r\n </div>\r\n</template>\r\n<script lang=\"ts\" setup>\r\n\r\nimport EditorJS from '@ebl-vue/editorjs';\r\n//import EditorJS from '../../../../editorjs/src/codex';\r\n//window.VERSION=\"2.31.0\"; //如果是用源码模式时,需要设置全局变量\r\n\r\nimport { onMounted, onUnmounted, ref, inject } from 'vue';\r\nimport { toRaw } from 'vue';\r\nimport { IEblEditorSettings } from '@/types';\r\n\r\n/**\r\n * 插件\r\n */\r\n\r\nimport DragDrop from '../../plugins/drag-drop';\r\nimport { H1, H2, H3, H4, H5, H6 } from '../../plugins/header';\r\nimport BlockAlignment from '../../plugins/block-alignment';\r\nimport Paragraph from '../../plugins/paragraph';\r\nimport Code from '../../plugins/code';\r\nimport type { OutputData } from '@ebl-vue/editorjs';\r\nimport Quote from \"../../plugins/quote/\";\r\nimport Delimiter from '../../plugins/delimiter';\r\nimport List from '../../plugins/list';\r\nimport Undo from '../../plugins/undo';\r\nimport Alert from '../../plugins/alert';\r\nimport IndentTune from '../../plugins/indent';\r\nimport Marker from \"../../plugins/marker\";\r\nimport { ColorPickerWithoutSanitize } from \"../../plugins/color-picker\";\r\nimport Underline from \"../../plugins/underline\";\r\nimport InlineCode from \"../../plugins/inline-code\";\r\nimport Table from '../../plugins/table';\r\nimport ImageTool from \"../../plugins/imageTool\";\r\nimport {ImageToolTune } from \"../../plugins/imageResizeCrop\";\r\n\r\nconst EblEditorSettings: IEblEditorSettings | undefined = inject(\"EblEditorSettings\");\r\n\r\ndefineOptions({\r\n name: 'EblEditor',\r\n inheritAttrs: false\r\n})\r\n\r\n\r\nlet emits = defineEmits([\"onReady\", \"onChange\"]);\r\n\r\n\r\ninterface Props {\r\n readOnly: boolean,\r\n placeholder: string,\r\n title: string,\r\n lastUpdateTime: string,\r\n data: OutputData,\r\n locale: any,\r\n userStore:any\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n readOnly: false,\r\n placeholder: \"Enter something\",\r\n title: \"\",\r\n lastUpdateTime: \"\",\r\n data: ()=>({\r\n blocks: []\r\n }),\r\n locale:{}\r\n});\r\n\r\n\r\nconst title = ref(props.title);\r\nlet editor: EditorJS | null = null;\r\nconst tunes = ['indent', 'blockAlignment'];\r\nonMounted(() => {\r\n const editorData=toRaw(props.data);\r\n editor = new EditorJS({\r\n holder: 'holder',\r\n autofocus: true,\r\n defaultBlock: 'paragraph',\r\n placeholder: props.placeholder,\r\n tunes: tunes,\r\n tools: {\r\n inlineCode: InlineCode,\r\n underline: Underline,\r\n Color: {\r\n class: ColorPickerWithoutSanitize\r\n },\r\n marker: {\r\n class: Marker\r\n },\r\n indent: {\r\n class: IndentTune,\r\n },\r\n alert: {\r\n class: Alert,\r\n inlineToolbar: true\r\n },\r\n List: {\r\n class: List,\r\n inlineToolbar: true,\r\n config: {\r\n defaultStyle: 'unordered',\r\n }\r\n },\r\n h1: {\r\n class: H1,\r\n inlineToolbar: true\r\n },\r\n h2: {\r\n class: H2,\r\n inlineToolbar: true,\r\n\r\n },\r\n h3: {\r\n class: H3,\r\n inlineToolbar: true\r\n },\r\n h4: {\r\n class: H4,\r\n inlineToolbar: true\r\n },\r\n h5: {\r\n class: H5,\r\n inlineToolbar: true\r\n },\r\n h6: {\r\n class: H6,\r\n inlineToolbar: true\r\n },\r\n paragraph: {\r\n class: Paragraph,\r\n inlineToolbar: true\r\n },\r\n blockAlignment: {\r\n class: BlockAlignment,\r\n inlineToolbar: true\r\n },\r\n code: {\r\n class: Code,\r\n config: {\r\n lang: \"javascript\",\r\n theme: \"catppuccin-latte\"\r\n }\r\n },\r\n quote: {\r\n class: Quote,\r\n inlineToolbar: true\r\n },\r\n delimiter: Delimiter,\r\n table: {\r\n class: Table,\r\n inlineToolbar: true,\r\n config: {\r\n rows: 2,\r\n cols: 3,\r\n }\r\n },\r\n image: {\r\n class: ImageTool,\r\n inlineToolbar: true,\r\n tunes: tunes.concat(['imageResize']),\r\n config: {\r\n types:\".png,.jpeg,.jpg,.gif,.webp\",\r\n userStore: props.userStore,\r\n endpoints: {\r\n byFile: EblEditorSettings?.fileUploadEndpoint,\r\n byUrl: EblEditorSettings?.urlUploadEndpoint\r\n },\r\n features: {\r\n caption: false,\r\n stretch: false,\r\n border: false,\r\n background: false,\r\n }\r\n \r\n \r\n }\r\n },\r\n imageResize: {\r\n class: ImageToolTune ,\r\n config: {\r\n resize: true,\r\n crop: false\r\n }\r\n },\r\n\r\n\r\n\r\n },\r\n \r\n data: editorData,\r\n readOnly: props.readOnly,\r\n i18n: props.locale,\r\n onChange: (api, event) => {\r\n emits(\"onChange\", api, event);\r\n },\r\n onReady: () => {\r\n new DragDrop(\"holder\", props.readOnly, editor!, '1px solid #999');\r\n const undoConfig = {\r\n debounceTimer: 200,\r\n maxLength:100\r\n }\r\n const undo = new Undo({\r\n editor: editor!,\r\n config: undoConfig,\r\n onUpdate: () => {\r\n }\r\n });\r\n undo.initialize(editorData);\r\n emits(\"onReady\");\r\n },\r\n\r\n })\r\n});\r\nonUnmounted(() => {\r\n if (editor !== null) {\r\n editor.destroy();\r\n editor = null;\r\n }\r\n});\r\n\r\n\r\nfunction save() {\r\n console.log(\"save\");\r\n if (editor !== null) {\r\n editor.save().then((outputData: OutputData) => {\r\n console.log('Article data saved in outputData', JSON.stringify(outputData));\r\n }).catch(error => {\r\n console.log('Saving failed: ', error);\r\n });\r\n }\r\n}\r\n\r\n</script>\r\n<style scoped></style>","\r\nimport type { Plugin } from \"vue\";\r\nimport { withInstall } from \"../utils/install\" \r\nimport type { SFCWithInstall } from 'types'\r\n\r\n\r\nimport Editor from \"./Editor/Editor.vue\"\r\n\r\n\r\n\r\n\r\nconst items = [ \r\n Editor \r\n];\r\n\r\nlet PluginList: Plugin[] = [];\r\nfor (let key in items) { \r\n const ele = items[key];\r\n const EblEle: SFCWithInstall<typeof ele> = withInstall(ele);\r\n \r\n PluginList.push(EblEle);\r\n}\r\n\r\nexport default PluginList;\r\nexport {\r\n Editor as EblEditor\r\n };","import type { I18nConfig } from \"@ebl-vue/editorjs/types/configs/i18n-config\";\r\n\r\nconst zhCn: I18nConfig = {\r\n messages: {\r\n \"ui\": {\r\n \"blockTunes\": {\r\n \"toggler\": {\r\n \"Click to tune\": \"可拖拽和点击\"\r\n },\r\n },\r\n\r\n \"toolbar\": {\r\n \"toolbox\": {\r\n \"Add\": \"添加\",\r\n \"Filter\": \"过滤\",\r\n \"Nothing found\": \"无内容\"\r\n },\r\n \"popover\": {\r\n \"Filter\": \"过滤\",\r\n \"Nothing found\": \"无内容\"\r\n }\r\n },\r\n \"popover\": {\r\n \"Filter\": \"筛选\",\r\n \"Nothing found\": \"未找到任何内容\",\r\n /**\r\n * Translation of \"Convert To\" at the Block Tunes Popover\r\n */\r\n \"Convert to\": \"转化为\",\r\n \r\n }\r\n },\r\n \"toolNames\": {\r\n \"Text\": \"段落\",\r\n \"H1\": \"一级标题\",\r\n \"H2\": \"二级标题\",\r\n \"H3\": \"三级标题\",\r\n \"H4\": \"四级标题\",\r\n \"H5\": \"五级标题\",\r\n \"H6\": \"六级标题\",\r\n \"Ordered List\": \"有序列表\",\r\n \"Unordered List\": \"无序列表\",\r\n \"Checklist\": \"任务列表\",\r\n \"Quote\": \"引用\",\r\n \"Code\": \"代码块\",\r\n \"Delimiter\": \"分割线\",\r\n \"Link\": \"链接\",\r\n \"Bold\": \"加粗\",\r\n \"Italic\": \"倾斜\",\r\n \"Alert\": \"高亮块\",\r\n \"indent\": \"缩进\",\r\n \"Marker\": \"突出显示\",\r\n \"Color\": \"文本颜色\",\r\n \"Underline\": \"下划线\",\r\n \"InlineCode\": \"行内代码\",\r\n \"Table\": \"表格\",\r\n \"Image\": \"图片\",\r\n\r\n\r\n\r\n },\r\n \"tools\": {\r\n image: {\r\n \"Couldn’t upload image. Please try another.\": \"上传图片失败,请稍后重试。\"\r\n },\r\n table: {\r\n \"Add row above\": \"在下面插入行\",\r\n \"Add row below\": \"在下面插入行\",\r\n \"Delete row\": \"删除行\",\r\n \"Add column to left\": \"在左边插入列\",\r\n \"Add column to right\": \"在右边插入列\",\r\n \"Delete column\": \"删除列\",\r\n \"With headings\": \"使用标题行\",\r\n \"Without headings\": \"不使用标题行\"\r\n\r\n\r\n },\r\n \"marker\": {\r\n \"Marker\": \"突出显示\"\r\n },\r\n link: {\r\n \"Add a link\":\"添加链接\",\r\n \"Save\": \"保存\",\r\n \"Pasted link is not valid.\":\"链接地址无效\"\r\n },\r\n \"List\": {\r\n \"Unordered\": \"无序\",\r\n \"Ordered\": \"有序\",\r\n \"Checklist\": \"任务列表\",\r\n \"Counter type\": \"计数器类型\",\r\n \"Numeric\": \"阿拉伯数字\",\r\n \"Lower Roman\": \"小写罗马数字\",\r\n \"Upper Roman\": \"大写罗马数字\",\r\n \"Lower Alpha\": \"小写字母\",\r\n \"Upper Alpha\": \"大写字母\",\r\n \"Start with\": \"从\"\r\n },\r\n \"paragraph\": {\r\n \"Enter something\": \"请输入内容\",\r\n },\r\n\r\n \"stub\": {\r\n 'The block can not be displayed correctly.': '该模块不能放置在这里'\r\n },\r\n\r\n \"code\": {\r\n \"Enter your code\": \"输入代码\",\r\n \"Copied\": \"已复制\"\r\n },\r\n \"convertTo\": {\r\n \"Convert to\": \"转化为\"\r\n },\r\n \"alert\": {\r\n \"alert-primary\": \"主要样式\",\r\n \"alert-secondary\": \"次要样式\",\r\n \"alert-info\": \"信息\",\r\n \"alert-success\": \"成功\",\r\n \"alert-warning\": \"警告\",\r\n \"alert-danger\": \"危险\",\r\n \"alert-light\": \"浅色\",\r\n \"alert-dark\": \"深色\",\r\n \"align-left\": \"左对齐\",\r\n \"align-center\": \"居中\",\r\n \"align-right\": \"右对齐\" \r\n }\r\n },\r\n \"blockTunes\": {\r\n \r\n \"delete\": {\r\n \"Delete\": \"删除\",\r\n 'Click to delete': \"点击删除\"\r\n },\r\n \"moveUp\": {\r\n \"Move up\": \"向上移\"\r\n },\r\n \"moveDown\": {\r\n \"Move down\": \"向下移\"\r\n },\r\n \"filter\": {\r\n \"Filter\": \"过滤\"\r\n },\r\n \"blockAlignment\": {\r\n \"left align\": \"左对齐\",\r\n \"center align\": \"居中对齐\",\r\n \"right align\": \"右对齐\",\r\n \"justify align\": \"两端对齐\",\r\n },\r\n \"indent\": {\r\n \"Indent right\": \"向右缩进\",\r\n \"Indent left\": \"向左缩进\"\r\n },\r\n },\r\n }\r\n}\r\n\r\nexport default zhCn;","\r\n\r\nimport './style.css'\r\nimport { createInstaller } from './installer'\r\nimport Components from './components';\r\nimport zhCn from './i18n/zh-cn';\r\nconst installer = createInstaller(Components)\r\nexport const install = installer.install\r\nexport const version = installer.version\r\nexport default installer;\r\nexport * from \"./components\";\r\nexport { zhCn };","import type { App, Plugin } from 'vue'\r\nimport { version } from '../package.json'\r\n\r\nimport { INSTALLED_KEY } from \"./constants\";\r\nimport { IEblEditorSettings } from '@/types';\r\n\r\nexport const createInstaller = (components: Plugin[] = []) => {\r\n const install = (app: App,config?: IEblEditorSettings) => {\r\n if (app[INSTALLED_KEY]) return\r\n\r\n app[INSTALLED_KEY] = true\r\n components.forEach((c) => app.use(c)) \r\n if(config) {\r\n app.provide(\"EblEditorSettings\",config);\r\n }\r\n \r\n }\r\n\r\n return {\r\n version,\r\n install,\r\n }\r\n}"],"names":["INSTALLED_KEY","Symbol","withInstall","main","extra","install","app","comp","Object","values","component","name","DragDrop","holderId","readonly","editor","borderStyle","blocks","toolbar","this","api","holder","document","getElementById","readOnly","startBlock","endBlock","setDragListener","setDropListener","element","range","createRange","selection","window","getSelection","setStart","childNodes","collapse","removeAllRanges","addRange","focus","settingsButton","querySelector","initializeDragListener","MutationObserver","mutations","obs","disconnect","observe","childList","subtree","setAttribute","addEventListener","getCurrentBlockIndex","close","isTheOnlyBlock","allBlocks","querySelectorAll","blockFocused","setElementCursor","setBorderBlocks","forEach","block","blockContent","style","removeProperty","index","keys","find","key","Number","borderBottom","borderTop","event","target","contains","dropTarget","getDropTarget","getTargetPosition","moveBlocks","classList","closest","Array","from","parentNode","children","indexOf","getBlocksCount","move","IconH1","IconH2","IconH3","IconH4","IconH5","IconH6","IconAlignCenter","IconAlignLeft","IconAlignRight","IconCross","IconMarker","IconPicture","IconText","IconIndentLeft","IconIndentRight","H1","data","config","_settings","placeholder","_data","normalizeData","_element","getTag","styles","wrapper","text","newData","level","defaultLevel","number","isHeaderData","isNaN","parseInt","toString","insertAdjacentHTML","blockData","trim","toolsContent","innerHTML","export","import","sanitize","newHeader","replaceChild","tag","createHeadingElement","setElementContent","addStylesToElement","setEditability","addPlaceholder","createElement","add","_CSS","contentEditable","dataset","i18n","t","svg","detail","content","tags","toolbox","icon","title","H2","H3","pasteConfig","H4","constructor","render","H5","isReadOnlySupported","H6","BlockAlignment","isTune","settings","hasOwnProperty","default","DEFAULT_ALIGNMENT","alignment","getAlignment","alignmentSettings","left","center","right","toggle","append","map","align","button","type","settingsButtonActive","buttonTooltip","tooltip","onHover","placement","appendChild","elements","el","i","Paragraph","onKeyUp","bind","_placeholder","DEFAULT_PLACEHOLDER","_preserveBlank","preserveBlank","e","code","textContent","drawView","div","placeholderActive","fragment","htmlString","tempDiv","createDocumentFragment","normalize","savedData","requestAnimationFrame","conversionConfig","br","CodeTool","_selectorLanguage","_selectorTheme","lang","DEFAULT_LANGUAGE","theme","DEFAULT_THEME","CSS","baseClass","input","textarea","span","selectorLanguage","selectorTheme","nodes","enableLineBreaks","codeWrapper","value","stopPropagation","preventDefault","isShiftPressed","shiftKey","caretPosition","selectionStart","indentation","newCaretPosition","currentLineStart","string","position","char","substr","substring","setSelectionRange","wrapperHolder","wrapperSelectorHolder","wrapperLang","wrapperCopy","wrapperCopyTip","innerText","languages","option","id","spellcheck","autocomplete","autocapitalize","disabled","runShiki","then","html","preStyle","tabHandler","copyCode","codeToHtml","transformers","preprocess","node","addClassToHast","properties","navigator","clipboard","writeText","parentEle","parentElement","lastChild","setTimeout","remove","catch","err","alert","Quote","contentless","quoteData","container","make","_quoteElement","handleKeydown","currentNode","anchorNode","nodeType","Node","ELEMENT_NODE","currentItem","getOutOfQuote","length","currentBlockIndex","delete","insert","caret","setToBlock","quoteElement","assign","Delimiter","lineWrapper","lineDiv","CssPrefix","DefaultListCssClasses","item","itemContent","itemChildren","OrderedListRenderer","orderedList","isRoot","wrapperElement","_meta","itemWrapper","contentNode","isEmpty","UnorderedListRenderer","unorderedList","composeDefaultMeta","isHtmlElement","CheckListRenderer","checklist","itemChecked","noHover","checkbox","checkboxContainer","checkboxCheckDisabled","toggleCheckbox","meta","checked","removeSpecialHoverBehavior","once","getSiblings","direction","siblings","nextElementSibling","getNextElementSibling","previousElementSibling","push","getChildItems","firstLevelChildren","itemChildWrapper","getItemChildWrapper","removeChildWrapperIfEmpty","getItemContentElement","focusItem","atStart","ListTabulator","currentItemLevel","levelCounter","listWrapper","renderer","renderWrapper","items","appendItems","enterPressed","backspace","shiftTab","addTab","start","changeStartWith","counterType","changeCounters","getItems","parent","subItemsWrapper","getItemContent","getItemMeta","composedListItems","dataToSave","deepestBlockItem","deepestBlockItemContentElement","firstLevelItems","lastFirstLevelItemChildWrapper","firstItem","shift","list","pasteHandler","oldView","tagName","tagToSearch","getPastedItems","child","subItems","setProperty","isComposing","isFirstLevelItem","isFirstItem","splitList","convertItemToDefaultBlock","unshiftItem","splitItem","isCaretAtStartOfInput","isCollapsed","mergeItemWithPrevious","convertFirstItemToDefaultBlock","parentItem","currentItemChildWrapper","sibling","after","currentItemChildrenList","currentBlock","firstChildItem","newListItems","newListWrapper","newListItem","newListContent","save","offset","getCaretNodeAndOffset","currentItemContent","endingHTML","getContenteditableSlice","itemEl","renderItem","previousItem","currentItemParentNode","targetItem","childrenOfPreviousItem","targetItemContentElement","targetForChildItems","targetChildWrapper","childItem","prepend","maxLevel","prevItem","previousSibling","prevItemChildrenList","prevItemChildrenListWrapper","newBloxkIndex","removeList","newBlock","currentItemChildren","currentItemSiblings","itemMeta","sublistWrapper","OlCounterTypesMap","Map","EditorjsList","joinRecursive","defaultStyle","defaultListStyle","changeTabulatorByStyle","newListElement","listElement","replaceWith","defaultCounterTypes","counterTypes","initialData","normalizedDataItems","structuredClone","listStyle","join","merge","onPaste","Observer","registerChange","debounceTimer","observer","mutationDebouncer","debounce","mutationList","mutationHandler","attributes","characterData","characterDataOldValue","contentMutated","mutation","onDestroy","callback","wait","timeout","args","context","clearTimeout","apply","destroyEvent","CustomEvent","dispatchEvent","Undo","onUpdate","maxLength","defaultOptions","shortcuts","undo","redo","configuration","defaultBlock","defaultShortcuts","configShortcuts","isArray","defaultDebounceTimer","shouldSaveHistory","setMutationObserver","setEventListeners","initialItem","clear","stack","limit","firstElement","state","setReadOnly","editorDidUpdate","JSON","stringify","truncate","Math","min","slice","blockCount","indexInState","caretIndex","getCaretIndex","getElementsByClassName","VanillaCaret","firstChild","getPos","compState","some","compIndex","canUndo","nextIndex","nextState","blockWasDeleted","insertDeletedBlock","contentWasCopied","blockWasSkipped","setCaretIndex","blockWasDropped","contentChangedInNoFocusBlock","getBlockByIndex","update","caretBlock","setPos","insertBlock","insertSkippedBlocks","prevState","updateModifiedBlock","getById","canRedo","prevIndex","count","specialKeys","CMD","test","platform","ALT","SHIFT","parsedKeys","letterKey","includes","toUpperCase","toLowerCase","keysUndo","undoShortcut","replace","split","keysRedo","redoShortcut","keysUndoParsed","parseKeys","keysRedoParsed","verifyListThreeKeysPressed","keysList","reduce","result","pressedKeys","compKeys","twoKeysPressed","verifyListTwoKeysPressed","handleUndo","handleRedo","removeEventListener","Alert","DEFAULT_TYPE","DEFAULT_ALIGN_TYPE","ALERT_TYPES","ALIGN_TYPES","wrapperForType","wrapperForAlignType","alignType","message","alertTypes","defaultType","defaultAlign","messagePlaceholder","DEFAULT_MESSAGE_PLACEHOLDER","containerClasses","_make","messageEl","classname","alertWrapper","alignWrapper","_getSettingIconStyle","buttons","getAttribute","_changeAlertType","elType","AlignLeftIcon","AlignRightIcon","AlignCenterIcon","_changeAlignType","elAlign","charAt","newType","alertClass","newAlign","alignClass","alertElement","classNames","attrName","warnings","orientation","IndentTune","other","DEFAULT_INDENT_KEY","lastResizeTimeout","cachedMaxWidthForContent","indentSize","maxIndent","minIndent","multiblock","autoIndent","tuneName","customBlockIndentLimits","handleShortcut","directionChangeHandler","version","changeConfigBasedOnVersionIfNeeded","alignmentChangeListener","defaultIndentLevel","indentLevel","onResize","call","events","on","targetId","currentBlockId","shouldApplyAutoIndent","queueMicrotask","autoIndentBlock","prepare","disableItemOnRender","getTuneButton","disabledItem","leftElementName","TuneNames","indentLeft","rightElementName","indentRight","rightText","hint","onActivate","handleIndentRight","leftText","handleIndentLeft","popoverItem","customPopoverItem","popoverItemIcon","popoverItemTitle","sanitizer","clean","createElementFromTemplate","rightBtn","leftBtn","pluginsContent","DATA_WRAPPER_NAME","applyBlockHighlight","Boolean","highlightIndent","tuneNames","highlightEl","className","contentEl","EditorCSS","applyStylesToWrapper","onKeyDown","capture","onFocus","onBlur","redactor","customInterval","max","isDirectionInverted","previousBlockIndex","previousBlock","previousBlockName","isDefaultKeyPressed","isCustomBehaviourDefined","handledCommand","isIndent","handlingResult","handlePropagationForKeyEvent","inlineToolbar","selectedBlocks","getGlobalSelectedBlocks","indentBlock","unIndentBlock","dispatchChange","async","b","tunes","tune","blockWrapper","getWrapperBlockById","HTMLElement","toggleDisableStateForButtons","getBlockIndex","previousBlockIndentLevelAttribute","DATA_INDENT_LEVEL","previousBlockIndentLevel","currentBlockIndentLevel","indentType","indentName","getTuneByName","givenWrapper","indentValue","contentElement","blockElement","getBlockForWrapper","blockWidth","getBoundingClientRect","width","maxApplyableIndent","maxWidthForContent","indentToApply","indentValuePixels","indentValuePixelsForHighlight","paddingLeft","paddingRight","highlightElement","DATA_FOCUSED","removeAttribute","w","fill","_","idx","filter","selected","blockId","selector","current","HTMLHtmlElement","indentRightBtnTitle","getTuneTitleByName","indentLeftBtnTitle","template","DOMParser","parseFromString","body","elementInsideEditor","maxWidth","getComputedStyle","_Ct","Marker","iconClasses","base","inlineToolButton","active","inlineToolButtonActive","isInline","toolboxIcon","termWrapper","findParentTag","unwrap","wrap","marker","extractContents","insertNode","expandToTag","sel","getRangeAt","unwrappedContent","removeChild","checkState","termTag","mark","class","ColorPicker","defaultColor","lastRange","colors","columns","color","selectedText","renderActions","gridTemplateColumns","colorValue","backgroundColor","onclick","wrapAndColor","ColorPickerWithoutSanitize","Underline","options","u","_bt","InlineCode","commonAncestorContainer","prototype","getCoords","elem","rect","y1","floor","top","pageYOffset","x1","pageXOffset","x2","y2","bottom","getRelativeCoordsOfTwoElems","firstElem","secondElem","firstCoords","secondCoords","fromTopBorder","fromLeftBorder","fromRightBorder","fromBottomBorder","insertBefore","newNode","referenceNode","selectNodeContents","Popover","itemEls","popover","popoverOpened","itemHidden","itemConfirmState","itemIcon","itemLabel","$.make","label","popoverClicked","clickedItem","clickedItemIndex","confirmationRequired","hasConfirmationState","onClick","setConfirmationState","opened","open","hideIf","clearConfirmationState","Toolbox","onOpen","onClose","cssModifier","createToolbox","toolboxShowed","toggler","mutationFree","createPopover","createToggler","togglerClicked","computePositionMethod","entries","prop","hide","Table","minCellWidhth","defaultCellWidth","handleDocumentMousedown","isDragging","table","handleDocumentMousemove","handleDocumentMouseup","draggingColumn","hoveredColumn","startWidth","colWidthArr","mouseStartX","clientX","deltaX","newWidth","updateColWidth","updateToolboxesPosition","hoveredCell","focusedCell","row","col","toolboxColumn","createColumnToolbox","toolboxRow","createRowToolbox","createTableWrapper","hoveredRow","selectedRow","selectedColumn","withHeadings","resize","colWidth","column","documentClicked","clickedInsideTable","outsideTableClicked","hideToolboxes","clickedOnAddRowButton","clickedOnAddColumnButton","addRow","addColumn","bindEvents","delay","fn","lastCall","now","Date","getTime","onMouseMoveInTable","passive","onkeypress","onKeyPressListener","onKeyDownListener","focusInTableListener","cells","cell","numberOfColumns","maxcols","deleteColumn","selectColumn","hideRowToolbox","unselectColumn","numberOfRows","maxrows","deleteRow","selectRow","hideColumnToolbox","unselectRow","focusCell","getCell","columnIndex","setFocus","numOfColumns","rowIndex","cellElem","createCell","$.insertBefore","getRow","firstCell","$.focus","addColButton","addHeadingAttrToFirstRow","splice","insertedRow","rowElem","removeHeadingAttrFromFirstRow","fillRow","insertedRowFirstCell","getRowFirstCell","addRowButton","computeInitialSize","isValidArray","isNotEmptyArray","contentRows","contentCols","parsedRows","rows","parsedCols","cols","configRows","configCols","j","setCellContent","newCell","childElementCount","deltaXCell","getHoveredCell","cellIsResizable","clientWidth","moveCursorToNextRow","getRowByCell","focusedCellElem","isColumnMenuShowing","show","isRowMenuShowing","hoveredRowElement","$.getRelativeCoordsOfTwoElems","height","ceil","cellIndex","x","y","clientY","beforeTheLeftBorder1","afterTheRightBorder1","binSearch","mid","beforeTheLeftBorder2","afterTheRightBorder2","deltaYCell","getMousePositionRelateToCell","deltaY","numberOfCells","beforeTheLeftBorder","afterTheRightBorder","leftBorder","rightBorder","totalIterations","relativeCoords","every","destroy","TableBlock","getConfig","stretched","getWrapper","setHeadingsSetting","renderSettings","isActive","closeOnActivate","tableContent","getData","configName","defaultValue","firstRowHeading","UiState","Ui","onSelectFile","imageContainer","fileButton","createFileButton","imageEl","imagePreloader","caption","captionPlaceholder","status","toggleStatus","src","backgroundImage","hidePreloader","url","eventName","autoplay","loop","muted","playsinline","statusType","loading","loader","buttonContent","Uploader","onUpload","onError","onPreview","noSelectedFile","cdn","objectKey","files","fileCancle","Promise","resolve","reject","inputElement","multiple","accept","display","click","types","file","reader","FileReader","readAsDataURL","onload","fileTypes","suffixIndex","lastIndexOf","suffix","headers","userStore","token","tokenName","tokenPrefix","axiosInstance","axios","create","uploadBodyRes","post","endpoints","byFile","fileName","contentType","statusText","uploadRes","success","put","presignedUrl","response","error","upload","byUrl","res","uploadByFile","ImageTool","isCaptionEnabled","additionalRequestData","additionalRequestHeaders","field","uploader","actions","features","uploadingFailed","ui","uploadSelectedFile","showPreloader","withBorder","withBackground","applyTune","concat","featureTuneMap","border","background","stretch","availableTunes","featureKey","currentState","action","newState","tuneToggled","appendCallback","img","mimeTypes","image","fetch","blob","uploadFile","uploadUrl","fillCaption","setTune","fillImage","errorText","errorMessage","notifier","deleteCurrentBlock","uploadByUrl","ImageToolTune","floatLeft","floatRight","sizeSmall","sizeMiddle","sizeLarge","resizeSize","crop","cropperFrameHeight","cropperFrameWidth","cropperFrameLeft","cropperFrameTop","cropperImageHeight","cropperImageWidth","cropperInterface","settingsButtonModifier","settingsButtonModifierActive","buttonActive","buttonModifier","buttonModifierActive","isFloatLeft","isFloatRight","isCenter","isSizeSmall","isSizeMiddle","isSizeLarge","isResize","isCrop","createView","tuneGroup","group","unresize","applyCrop","uncrop","isEnabled","cropBtn","appendCrop","cdxBlock","getElementsByTagName","Cropper","cropSaveBtn","getCropBoxData","getCanvasData","getImageData","blockEl","minWidth","blockImg","imageToolImage","resizable","resizers","resizerTopRight","resizeClick","resizerBottomRight","startX","mouseMoveHandler","dx","mouseUpHandler","unresizable","buttonIco","buttonTxt","fontSize","tuneClicked","tuneNameToI18nKey","isTuneActive","view","EblEditorSettings","inject","emits","__emit","props","__props","ref","outputData","onMounted","editorData","toRaw","EditorJS","autofocus","tools","inlineCode","underline","Color","indent","List","h1","h2","h3","h4","h5","h6","paragraph","blockAlignment","Code","quote","delimiter","fileUploadEndpoint","urlUploadEndpoint","imageResize","locale","onChange","onReady","initialize","onUnmounted","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","$event","_hoisted_3","_hoisted_4","lastUpdateTime","Editor","PluginList","EblEle","zhCn","messages","blockTunes","Add","Filter","toolNames","Text","Checklist","Link","Bold","Italic","Image","link","Save","Unordered","Ordered","Numeric","stub","Copied","convertTo","Delete","moveUp","moveDown","installer","components","c","use","provide","createInstaller","Components"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/constants/index.ts","../src/utils/install.ts","../src/plugins/drag-drop/index.ts","../src/icons/index.ts","../src/plugins/header/H1.ts","../src/plugins/header/H2.ts","../src/plugins/header/H3.ts","../src/plugins/header/H4.ts","../src/plugins/header/H5.ts","../src/plugins/header/H6.ts","../src/plugins/block-alignment/index.ts","../src/plugins/paragraph/index.ts","../src/plugins/paragraph/utils/makeFragment.ts","../src/plugins/code/index.ts","../src/plugins/code/utils/string.ts","../src/plugins/quote/index.ts","../src/plugins/delimiter/index.ts","../src/plugins/list/styles/CssPrefix.ts","../src/plugins/list/ListRenderer/ListRenderer.ts","../src/plugins/list/ListRenderer/OrderedListRenderer.ts","../src/plugins/list/ListRenderer/UnorderedListRenderer.ts","../src/plugins/list/utils/type-guards.ts","../src/plugins/list/ListRenderer/ChecklistRenderer.ts","../src/plugins/list/utils/getSiblings.ts","../src/plugins/list/utils/getChildItems.ts","../src/plugins/list/utils/getItemChildWrapper.ts","../src/plugins/list/utils/removeChildWrapperIfEmpty.ts","../src/plugins/list/utils/getItemContentElement.ts","../src/plugins/list/utils/focusItem.ts","../src/plugins/list/ListTabulator/index.ts","../src/plugins/list/utils/isLastItem.ts","../src/plugins/list/utils/itemHasSublist.ts","../src/plugins/list/types/OlCounterType.ts","../src/plugins/list/index.ts","../src/plugins/list/utils/normalizeData.ts","../src/plugins/undo/observer.ts","../src/plugins/undo/index.ts","../src/plugins/alert/index.ts","../src/plugins/indent/index.ts","../src/plugins/marker/index.ts","../src/plugins/color-picker/index.ts","../src/plugins/underline/index.ts","../src/plugins/inline-code/index.ts","../src/plugins/table/utils/dom.ts","../src/plugins/table/utils/popover.ts","../src/plugins/table/toolbox.ts","../src/plugins/table/table.ts","../src/plugins/table/utils/throttled.ts","../src/plugins/table/plugin.ts","../src/plugins/imageTool/utils/dom.ts","../src/plugins/imageTool/ui.ts","../src/plugins/imageTool/uploader.ts","../src/plugins/imageTool/utils/index.ts","../src/plugins/imageTool/index.ts","../src/plugins/imageResizeCrop/ImageTune.ts","../src/components/Editor/Editor.vue","../src/components/index.ts","../src/i18n/zh-cn.ts","../src/index.ts","../src/installer.ts"],"sourcesContent":["export const INSTALLED_KEY = Symbol('INSTALLED_KEY')\r\n","import type { SFCWithInstall } from 'types'\r\nimport type {App} from 'vue'\r\nexport const withInstall = <T, E extends Record<string, any>>(\r\n main: T,\r\n extra?: E\r\n) => {\r\n ;(main as SFCWithInstall<T>).install = (app:App): void => {\r\n for (const comp of [main, ...Object.values(extra ?? {})]) {\r\n app.component(comp.name, comp)\r\n }\r\n }\r\n\r\n if (extra) {\r\n for (const [key, comp] of Object.entries(extra)) {\r\n ;(main as any)[key] = comp\r\n }\r\n }\r\n return main as SFCWithInstall<T> & E\r\n}","import './index.css';\r\n\r\nimport type EditorJS from '@ebl-vue/editorjs/types';\r\n\r\nexport default class DragDrop {\r\n private toolbar: any;\r\n private borderStyle: string;\r\n private api: any;\r\n private holder: HTMLElement;\r\n private readOnly: boolean | undefined;\r\n private startBlock: number | null;\r\n private endBlock: number | null;\r\n\r\n constructor(\r\n holderId: string,\r\n readonly: boolean,\r\n editor: EditorJS, \r\n borderStyle: string) {\r\n const {\r\n blocks,\r\n toolbar,\r\n } = editor;\r\n this.toolbar = toolbar;\r\n this.borderStyle = borderStyle || '1px dashed #aaa';\r\n this.api = blocks;\r\n this.holder = document.getElementById(holderId) as HTMLElement;\r\n this.readOnly =readonly;\r\n this.startBlock = null;\r\n this.endBlock = null;\r\n\r\n\r\n this.setDragListener();\r\n this.setDropListener();\r\n }\r\n\r\n\r\n setElementCursor(element: HTMLElement|null) {\r\n if (!element) return;\r\n const range = document.createRange();\r\n const selection = window.getSelection();\r\n\r\n range.setStart(element.childNodes[0], 0);\r\n range.collapse(true);\r\n selection?.removeAllRanges();\r\n selection?.addRange(range);\r\n element.focus();\r\n }\r\n\r\n\r\n setDragListener() {\r\n if (!this.readOnly) {\r\n const settingsButton = this.holder?.querySelector<HTMLElement>('.ce-toolbar__settings-btn');\r\n if (settingsButton) {\r\n this.initializeDragListener(settingsButton);\r\n } else {\r\n const observer = new MutationObserver((mutations, obs) => {\r\n const settingsButton = this.holder?.querySelector<HTMLElement>(\r\n \".ce-toolbar__settings-btn\"\r\n );\r\n if (settingsButton) {\r\n this.initializeDragListener(settingsButton);\r\n obs.disconnect();\r\n }\r\n });\r\n\r\n observer.observe(this.holder, {\r\n childList: true,\r\n subtree: true,\r\n });\r\n }\r\n }\r\n }\r\n\r\n initializeDragListener(settingsButton: HTMLElement) {\r\n settingsButton.setAttribute(\"draggable\", \"true\");\r\n settingsButton.addEventListener(\"dragstart\", () => {\r\n this.startBlock = this.api.getCurrentBlockIndex();\r\n });\r\n settingsButton.addEventListener('drag', () => {\r\n this.toolbar.close(); \r\n if (!this.isTheOnlyBlock()) {\r\n const allBlocks = this.holder.querySelectorAll('.ce-block') as NodeListOf<HTMLElement>;\r\n const blockFocused = this.holder.querySelector<HTMLElement>('.ce-block--drop-target');\r\n this.setElementCursor(blockFocused);\r\n this.setBorderBlocks(allBlocks, blockFocused);\r\n }\r\n });\r\n }\r\n \r\n\r\n\r\n setBorderBlocks(allBlocks: NodeListOf<HTMLElement>, blockFocused: HTMLElement|null) {\r\n Object.values(allBlocks).forEach((block: HTMLElement) => {\r\n const blockContent = block.querySelector<HTMLElement>('.ce-block__content');\r\n if (block !== blockFocused) {\r\n blockContent?.style.removeProperty('border-top');\r\n blockContent?.style.removeProperty('border-bottom');\r\n } else {\r\n const index = Object.keys(allBlocks).find((key) => allBlocks[Number(key)] === blockFocused);\r\n if (index && Number(index) > this.startBlock!) blockContent!.style.borderBottom = this.borderStyle;\r\n else blockContent!.style.borderTop = this.borderStyle;\r\n }\r\n });\r\n }\r\n\r\n\r\n setDropListener() {\r\n document.addEventListener('drop', (event: DragEvent) => {\r\n const { target } = event;\r\n if (this.holder.contains(target as HTMLElement) && this.startBlock !== null) {\r\n const dropTarget = this.getDropTarget(target as HTMLElement);\r\n if (dropTarget) {\r\n const blockContent = dropTarget.querySelector<HTMLElement>('.ce-block__content');\r\n blockContent?.style.removeProperty('border-top');\r\n blockContent?.style.removeProperty('border-bottom');\r\n this.endBlock = this.getTargetPosition(dropTarget as HTMLElement);\r\n this.moveBlocks();\r\n }\r\n }\r\n this.startBlock = null;\r\n });\r\n }\r\n\r\n \r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n \r\n getDropTarget(target: HTMLElement) {\r\n return target.classList.contains('ce-block')\r\n ? target\r\n : target.closest('.ce-block');\r\n }\r\n\r\n\r\n getTargetPosition(target: HTMLElement) {\r\n return Array.from(target.parentNode!.children).indexOf(target);\r\n }\r\n\r\n isTheOnlyBlock() {\r\n return this.api.getBlocksCount() === 1;\r\n }\r\n\r\n\r\n moveBlocks() {\r\n if (!this.isTheOnlyBlock()) {\r\n this.api.move(this.endBlock, this.startBlock);\r\n }\r\n }\r\n}\r\n","export const IconH1: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19 17V10.2135C19 10.1287 18.9011 10.0824 18.836 10.1367L16 12.5\"/></svg>';\r\nexport const IconH2: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 11C16 10 19 9.5 19 12C19 13.9771 16.0684 13.9997 16.0012 16.8981C15.9999 16.9533 16.0448 17 16.1 17L19.3 17\"/></svg>';\r\nexport const IconH3: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 11C16 10.5 16.8323 10 17.6 10C18.3677 10 19.5 10.311 19.5 11.5C19.5 12.5315 18.7474 12.9022 18.548 12.9823C18.5378 12.9864 18.5395 13.0047 18.5503 13.0063C18.8115 13.0456 20 13.3065 20 14.8C20 16 19.5 17 17.8 17C17.8 17 16 17 16 16.3\"/></svg>';\r\nexport const IconH4: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 10L15.2834 14.8511C15.246 14.9178 15.294 15 15.3704 15C16.8489 15 18.7561 15 20.2 15M19 17C19 15.7187 19 14.8813 19 13.6\"/></svg>';\r\nexport const IconH5: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 15.9C16 15.9 16.3768 17 17.8 17C19.5 17 20 15.6199 20 14.7C20 12.7323 17.6745 12.0486 16.1635 12.9894C16.094 13.0327 16 12.9846 16 12.9027V10.1C16 10.0448 16.0448 10 16.1 10H19.8\"/></svg>';\r\nexport const IconH6: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19.5 10C16.5 10.5 16 13.3285 16 15M16 15V15C16 16.1046 16.8954 17 18 17H18.3246C19.3251 17 20.3191 16.3492 20.2522 15.3509C20.0612 12.4958 16 12.6611 16 15Z\"/></svg>';\r\nexport const IconAddBackground: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11 19V19C9.13623 19 8.20435 19 7.46927 18.6955C6.48915 18.2895 5.71046 17.5108 5.30448 16.5307C5 15.7956 5 14.8638 5 13V12C5 9.19108 5 7.78661 5.67412 6.77772C5.96596 6.34096 6.34096 5.96596 6.77772 5.67412C7.78661 5 9.19108 5 12 5H13.5C14.8956 5 15.5933 5 16.1611 5.17224C17.4395 5.56004 18.44 6.56046 18.8278 7.83886C19 8.40666 19 9.10444 19 10.5V10.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 13V16M16 19V16M19 16H16M16 16H13\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6.5 17.5L17.5 6.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18.9919 10.5H19.0015\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10.9919 19H11.0015\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13L13 5\"/></svg>';\r\nexport const IconAddBorder: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18.9919 9.5H19.0015\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.5 5H14.5096\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M14.625 5H15C17.2091 5 19 6.79086 19 9V9.375\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M9.375 5L9 5C6.79086 5 5 6.79086 5 9V9.375\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.3725 5H9.38207\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 9.5H5.00957\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M9.375 19H9C6.79086 19 5 17.2091 5 15V14.625\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.3725 19H9.38207\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 14.55H5.00957\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 13V16M16 19V16M19 16H16M16 16H13\"/></svg>';\r\nexport const IconAlignCenter: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 7L6 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 17H6\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 12L8 12\"/></svg>';\r\nexport const IconAlignJustify: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 7L6 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 17H6\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 12L6 12\"/></svg>';\r\nexport const IconAlignLeft: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M17 7L5 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M17 17H5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M13 12L5 12\"/></svg>';\r\nexport const IconAlignRight: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19 7L7 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19 17H7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19 12L11 12\"/></svg>';\r\nexport const IconBold: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M9 12L9 7.1C9 7.04477 9.04477 7 9.1 7H10.4C11.5 7 14 7.1 14 9.5C14 9.5 14 12 11 12M9 12V16.8C9 16.9105 9.08954 17 9.2 17H12.5C14 17 15 16 15 14.5C15 11.7046 11 12 11 12M9 12H11\"/></svg>';\r\nexport const IconBracketsVertical: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" fill=\"none\" viewBox=\"0 0 20 20\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.6\" d=\"M13.3333 7.5L10 4.16667L6.66668 7.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.6\" d=\"M13.3333 12.5L10 15.8333L6.66668 12.5\"/></svg>';\r\nexport const IconBrackets: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 8L5 12L9 16\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 8L19 12L15 16\"/></svg>';\r\nexport const IconCheck: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7 12L10.4884 15.8372C10.5677 15.9245 10.705 15.9245 10.7844 15.8372L17 9\"/></svg>';\r\nexport const IconChecklist: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M9.2 12L11.0586 13.8586C11.1367 13.9367 11.2633 13.9367 11.3414 13.8586L14.7 10.5\"/><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/></svg>';\r\nexport const IconChevronDown: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7 10L11.8586 14.8586C11.9367 14.9367 12.0633 14.9367 12.1414 14.8586L17 10\"/></svg>';\r\nexport const IconChevronLeft: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M14.5 17.5L9.64142 12.6414C9.56331 12.5633 9.56331 12.4367 9.64142 12.3586L14.5 7.5\"/></svg>';\r\nexport const IconChevronRight: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M9.58284 17.5L14.4414 12.6414C14.5195 12.5633 14.5195 12.4367 14.4414 12.3586L9.58284 7.5\"/></svg>';\r\nexport const IconChevronUp: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7 15L11.8586 10.1414C11.9367 10.0633 12.0633 10.0633 12.1414 10.1414L17 15\"/></svg>';\r\nexport const IconClipboard: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.42857 7H7.71429C7.25963 7 6.82359 7.15804 6.5021 7.43934C6.18061 7.72064 6 8.10218 6 8.5V17.5C6 17.8978 6.18061 18.2794 6.5021 18.5607C6.82359 18.842 7.25963 19 7.71429 19H16.2857C16.7404 19 17.1764 18.842 17.4979 18.5607C17.8194 18.2794 18 17.8978 18 17.5V8.5C18 8.10218 17.8194 7.72064 17.4979 7.43934C17.1764 7.15804 16.7404 7 16.2857 7H14.5714\"/><rect width=\"5.15789\" height=\"3.36842\" x=\"9.42105\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"1.5\"/></svg>';\r\nexport const IconCollapse: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 9L10 12M10 12L7 15M10 12H4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M17 9L14 12M14 12L17 15M14 12H20\"/></svg>';\r\nexport const IconColor: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5.24296 11.4075C5.23167 10.6253 5.52446 9.8395 6.12132 9.24264L9.65686 5.70711C10.0474 5.31658 10.6809 5.31693 11.0714 5.70745L16.0205 10.6565C16.2268 10.8629 16.3243 11.1371 16.3126 11.4075M5.24296 11.4075C5.25382 12.1607 5.54661 12.9106 6.12132 13.4853L8 15.364M5.24296 11.4075H11.9565M16.3126 11.4075C16.3022 11.6487 16.205 11.8869 16.0208 12.0711L12.4853 15.6066C11.3137 16.7782 9.41421 16.7782 8.24264 15.6066L8 15.364M16.3126 11.4075H11.9565M8 15.364L11.9565 11.4075\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M20 17.4615C20 18.3112 19.3284 19 18.5 19C17.6716 19 17 18.3112 17 17.4615C17 16.6119 17.9 15.6154 18.5 15C19.1 15.6154 20 16.6119 20 17.4615Z\"/></svg>';\r\nexport const IconCopy: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M17.25 8.5H10.25C9.2835 8.5 8.5 9.2835 8.5 10.25V17.25C8.5 18.2165 9.2835 19 10.25 19H17.25C18.2165 19 19 18.2165 19 17.25V10.25C19 9.2835 18.2165 8.5 17.25 8.5Z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15.5 8.5V6.75C15.5 6.28587 15.3156 5.84075 14.9874 5.51256C14.6592 5.18437 14.2141 5 13.75 5H6.75C6.28587 5 5.84075 5.18437 5.51256 5.51256C5.18437 5.84075 5 6.28587 5 6.75V13.75C5 14.2141 5.18437 14.6592 5.51256 14.9874C5.84075 15.3156 6.28587 15.5 6.75 15.5H8.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 12L15.5 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 15.5L15.5 15.5\"/></svg>';\r\nexport const IconCross: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M8 8L12 12M12 12L16 16M12 12L16 8M12 12L8 16\"/></svg>';\r\nexport const IconCurlyBrackets: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 17C7 17 7 15.2536 7 13.5L5.5 12L7 10.5C7 8.74644 7 7 9 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 17C17 17 17 15.2536 17 13.5L18.5 12L17 10.5C17 8.74644 17 7 15 7\"/></svg>';\r\nexport const IconDelimiter: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><line x1=\"6\" x2=\"10\" y1=\"12\" y2=\"12\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><line x1=\"14\" x2=\"18\" y1=\"12\" y2=\"12\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/></svg>';\r\nexport const IconDirectionDownRight: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.8833 9.16666L18.2167 12.5M18.2167 12.5L14.8833 15.8333M18.2167 12.5H10.05C9.16594 12.5 8.31809 12.1488 7.69297 11.5237C7.06785 10.8986 6.71666 10.0507 6.71666 9.16666\"/></svg>';\r\nexport const IconDirectionLeftDown: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.9167 14.9167L11.5833 18.25M11.5833 18.25L8.25 14.9167M11.5833 18.25L11.5833 10.0833C11.5833 9.19928 11.9345 8.35143 12.5596 7.72631C13.1848 7.10119 14.0326 6.75 14.9167 6.75\"/></svg>';\r\nexport const IconDirectionRightDown: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.13333 14.9167L12.4667 18.25M12.4667 18.25L15.8 14.9167M12.4667 18.25L12.4667 10.0833C12.4667 9.19928 12.1155 8.35143 11.4904 7.72631C10.8652 7.10119 10.0174 6.75 9.13333 6.75\"/></svg>';\r\nexport const IconDirectionUpRight: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.8833 15.8333L18.2167 12.5M18.2167 12.5L14.8833 9.16667M18.2167 12.5L10.05 12.5C9.16595 12.5 8.31811 12.8512 7.69299 13.4763C7.06787 14.1014 6.71667 14.9493 6.71667 15.8333\"/></svg>';\r\nexport const IconDotCircle: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"4\" stroke=\"currentColor\" stroke-width=\"2\"/></svg>';\r\nexport const IconEtcHorisontal: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M7.30499 11.995L7.30499 12.005M12.005 11.995V12.005M16.705 11.995L16.705 12.005\"/></svg>';\r\nexport const IconEtcVertical: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M12.01 7.29999H12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M12.01 12H12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M12.01 16.7H12\"/></svg>';\r\nexport const IconFile: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13.3236 8.43554L9.49533 12.1908C9.13119 12.5505 8.93118 13.043 8.9393 13.5598C8.94741 14.0767 9.163 14.5757 9.53862 14.947C9.91424 15.3182 10.4191 15.5314 10.9422 15.5397C11.4653 15.5479 11.9637 15.3504 12.3279 14.9908L16.1562 11.2355C16.8845 10.5161 17.2845 9.53123 17.2682 8.4975C17.252 7.46376 16.8208 6.46583 16.0696 5.72324C15.3184 4.98066 14.3086 4.55425 13.2624 4.53782C12.2162 4.52138 11.2193 4.91627 10.4911 5.63562L6.66277 9.39093C5.57035 10.4699 4.97032 11.9473 4.99467 13.4979C5.01903 15.0485 5.66578 16.5454 6.79264 17.6592C7.9195 18.7731 9.43417 19.4127 11.0034 19.4374C12.5727 19.462 14.068 18.8697 15.1604 17.7907L18.9887 14.0354\"/></svg>';\r\nexport const IconGift: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"12\" height=\"6\" x=\"6\" y=\"13\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"2\"/><line x1=\"12\" x2=\"12\" y1=\"9\" y2=\"19\" stroke=\"currentColor\" stroke-width=\"2\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5 11C5 9.89543 5.89543 9 7 9H17C18.1046 9 19 9.89543 19 11V11C19 12.1046 18.1046 13 17 13H7C5.89543 13 5 12.1046 5 11V11Z\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M16 9C16 7.89543 16 6 14 6C12 6 12 7.89543 12 9C12 7.89543 12 6 10 6C8 6 8 7.89543 8 9\"/></svg>';\r\nexport const IconGlobe: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M18 12C18 15.3137 15.3137 18 12 18C8.68629 18 6 15.3137 6 12M18 12C18 8.68629 15.3137 6 12 6C8.68629 6 6 8.68629 6 12M18 12H6M11.7 6C11.7 6 9.7 7.63811 9.7 12C9.7 16.9 11.7 18 11.7 18M12.3 6C12.3 6 14.3 7.63811 14.3 12C14.3 16.9 12.3 18 12.3 18\"/></svg>';\r\nexport const IconHeading: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M9 7L9 12M9 17V12M9 12L15 12M15 7V12M15 17L15 12\"/></svg>';\r\nexport const IconHeart: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M6.6 7.50001C5.27451 8.82549 5.19999 10.6 6.59999 12.3C8 14 12.2 17.9 12.2 17.9C12.2 17.9 16.5 14 17.8 12.3C19.1 10.6 19.1255 8.82549 17.8 7.5C16.4745 6.17452 14.3255 6.17452 13 7.5L12.2 8.30001L11.4 7.50001C10.0745 6.17453 7.92548 6.17453 6.6 7.50001Z\"/></svg>';\r\nexport const IconHidden: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6.77778 6L18.5 17.7222\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10.687 10C10.2473 10.4392 10.0002 11.035 10 11.6564C9.99978 12.2777 10.2465 12.8737 10.6858 13.3132C11.1251 13.7527 11.7211 13.9998 12.3427 14C12.9642 14.0002 13.5604 13.7536 14 13.3144\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 7C17 11.1666 20 11.17 20 11.67C20 12.17 19 13.17 19 13.17M8.2424 8.80936C7.59317 9.22876 6.97961 9.76732 6.4017 10.4251C5.70398 11.2193 5.35512 11.6164 5.35513 12.3702C5.35514 13.124 5.70406 13.5211 6.40191 14.3154C7.99587 16.1297 9.8618 17.0367 12 17.0367C13.1102 17.0367 14.1466 16.7917 15.1111 16.3024\"/></svg>';\r\nexport const IconHtml: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16.6954 5C17.912 5 18.8468 6.07716 18.6755 7.28165L17.426 16.0659C17.3183 16.8229 16.7885 17.4522 16.061 17.6873L12.6151 18.8012C12.2152 18.9304 11.7848 18.9304 11.3849 18.8012L7.93898 17.6873C7.21148 17.4522 6.6817 16.8229 6.57403 16.0659L5.32454 7.28165C5.15322 6.07716 6.088 5 7.30461 5H16.6954Z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 8.4H9L9.42857 11.7939H14.5714L14.3571 13.2788L14.1429 14.7636L12 15.4L9.85714 14.7636L9.77143 14.3394\"/></svg>';\r\nexport const IconInstagram: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M15.9 8.1V8.11\"/><circle cx=\"12\" cy=\"12\" r=\"3\" stroke=\"currentColor\" stroke-width=\"2\"/></svg>';\r\nexport const IconItalic: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M13.34 10C12.4223 12.7337 11 17 11 17\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M14.21 7H14.2\"/></svg>';\r\nexport const IconLink: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7.69998 12.6L7.67896 12.62C6.53993 13.7048 6.52012 15.5155 7.63516 16.625V16.625C8.72293 17.7073 10.4799 17.7102 11.5712 16.6314L13.0263 15.193C14.0703 14.1609 14.2141 12.525 13.3662 11.3266L13.22 11.12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16.22 11.12L16.3564 10.9805C17.2895 10.0265 17.3478 8.5207 16.4914 7.49733V7.49733C15.5691 6.39509 13.9269 6.25143 12.8271 7.17675L11.3901 8.38588C10.0935 9.47674 9.95706 11.4241 11.0888 12.6852L11.12 12.72\"/></svg>';\r\nexport const IconLinkedin: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/><line x1=\"9\" x2=\"9\" y1=\"11.4\" y2=\"15.4\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M9 8.7V8.71\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12 11.4V12M12 15.4V12M12 12C14 11.5 15 11.3611 15 12.5C15 13.5 15 15.4 15 15.4\"/></svg>';\r\nexport const IconListBulleted: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><line x1=\"9\" x2=\"19\" y1=\"7\" y2=\"7\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><line x1=\"9\" x2=\"19\" y1=\"12\" y2=\"12\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><line x1=\"9\" x2=\"19\" y1=\"17\" y2=\"17\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M5.00001 17H4.99002\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M5.00001 12H4.99002\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M5.00001 7H4.99002\"/></svg>';\r\nexport const IconListNumbered: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><line x1=\"12\" x2=\"19\" y1=\"7\" y2=\"7\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><line x1=\"12\" x2=\"19\" y1=\"12\" y2=\"12\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><line x1=\"12\" x2=\"19\" y1=\"17\" y2=\"17\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7.79999 14L7.79999 7.2135C7.79999 7.12872 7.7011 7.0824 7.63597 7.13668L4.79999 9.5\"/></svg>';\r\nexport const IconLoader: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12 6.99998C9.1747 6.99987 6.99997 9.24998 7 12C7.00003 14.55 9.02119 17 12 17C14.7712 17 17 14.75 17 12\"><animateTransform attributeName=\"transform\" attributeType=\"XML\" dur=\"560ms\" from=\"0,12,12\" repeatCount=\"indefinite\" to=\"360,12,12\" type=\"rotate\"/></path></svg>';\r\nexport const IconMarker: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M11.3535 9.31802L12.7678 7.90381C13.5488 7.12276 14.8151 7.12276 15.5962 7.90381C16.3772 8.68486 16.3772 9.95119 15.5962 10.7322L14.182 12.1464M11.3535 9.31802L7.96729 12.7043C7.40889 13.2627 7.02826 13.9739 6.87339 14.7482L6.69798 15.6253C6.55803 16.325 7.17495 16.942 7.87467 16.802L8.75175 16.6266C9.52612 16.4717 10.2373 16.0911 10.7957 15.5327L14.182 12.1464M11.3535 9.31802L14.182 12.1464\"/><line x1=\"15\" x2=\"19\" y1=\"17\" y2=\"17\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/></svg>';\r\nexport const IconMenuSmall: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M9.41 9.66H9.4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M14.6 9.66H14.59\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M9.31 14.36H9.3\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M14.6 14.36H14.59\"/></svg>';\r\nexport const IconMenu: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M9.40999 7.29999H9.4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M14.6 7.29999H14.59\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M9.30999 12H9.3\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M14.6 12H14.59\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M9.40999 16.7H9.4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M14.6 16.7H14.59\"/></svg>';\r\nexport const IconPicture: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5.13968 15.32L8.69058 11.5661C9.02934 11.2036 9.48873 11 9.96774 11C10.4467 11 10.9061 11.2036 11.2449 11.5661L15.3871 16M13.5806 14.0664L15.0132 12.533C15.3519 12.1705 15.8113 11.9668 16.2903 11.9668C16.7693 11.9668 17.2287 12.1705 17.5675 12.533L18.841 13.9634\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13.7778 9.33331H13.7867\"/></svg>';\r\nexport const IconPlay: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M10 10.5606V13.4394C10 14.4777 11.1572 15.0971 12.0211 14.5211L14.1803 13.0817C14.9536 12.5661 14.9503 11.4317 14.18 10.9181L12.0214 9.47907C11.1591 8.9042 10 9.5203 10 10.5606Z\"/><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/></svg>';\r\nexport const IconPlus: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12 7V12M12 17V12M17 12H12M12 12H7\"/></svg>';\r\nexport const IconQuestion: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12 15.52V15.51\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M10.0024 9.97655C10.1567 9.01858 11 8.5 12 8.5C13 8.5 13.6857 9.17188 13.8693 9.70703C14.0529 10.2422 14.0135 11.0514 13.5067 11.5159C13 11.9805 12.7344 11.832 12.2784 12.3168C12.1134 12.4923 12 12.7476 12 12.7476\"/></svg>';\r\nexport const IconQuote: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 10.8182L9 10.8182C8.80222 10.8182 8.60888 10.7649 8.44443 10.665C8.27998 10.5651 8.15181 10.4231 8.07612 10.257C8.00043 10.0909 7.98063 9.90808 8.01922 9.73174C8.0578 9.55539 8.15304 9.39341 8.29289 9.26627C8.43275 9.13913 8.61093 9.05255 8.80491 9.01747C8.99889 8.98239 9.19996 9.00039 9.38268 9.0692C9.56541 9.13801 9.72159 9.25453 9.83147 9.40403C9.94135 9.55353 10 9.72929 10 9.90909L10 12.1818C10 12.664 9.78929 13.1265 9.41421 13.4675C9.03914 13.8084 8.53043 14 8 14\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16 10.8182L15 10.8182C14.8022 10.8182 14.6089 10.7649 14.4444 10.665C14.28 10.5651 14.1518 10.4231 14.0761 10.257C14.0004 10.0909 13.9806 9.90808 14.0192 9.73174C14.0578 9.55539 14.153 9.39341 14.2929 9.26627C14.4327 9.13913 14.6109 9.05255 14.8049 9.01747C14.9989 8.98239 15.2 9.00039 15.3827 9.0692C15.5654 9.13801 15.7216 9.25453 15.8315 9.40403C15.9414 9.55353 16 9.72929 16 9.90909L16 12.1818C16 12.664 15.7893 13.1265 15.4142 13.4675C15.0391 13.8084 14.5304 14 14 14\"/></svg>';\r\nexport const IconRedo: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.6667 13.6667L18 10.3333L14.6667 7M18 10.3333H8.83333C7.94928 10.3333 7.10143 10.6845 6.47631 11.3096C5.85119 11.9348 5.5 12.7826 5.5 13.6667C5.5 14.5507 5.85119 15.3986 6.47631 16.0237C7.10143 16.6488 7.94928 17 8.83333 17H9.66667\"/></svg>';\r\nexport const IconRemoveBackground: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11 19V19C9.13623 19 8.20435 19 7.46927 18.6955C6.48915 18.2895 5.71046 17.5108 5.30448 16.5307C5 15.7956 5 14.8638 5 13V12C5 9.19108 5 7.78661 5.67412 6.77772C5.96596 6.34096 6.34096 5.96596 6.77772 5.67412C7.78661 5 9.19108 5 12 5H13.5C14.8956 5 15.5933 5 16.1611 5.17224C17.4395 5.56004 18.44 6.56046 18.8278 7.83886C19 8.40666 19 9.10444 19 10.5V10.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19.1187 14.8787L16.9974 17M14.876 19.1213L16.9974 17M19.1187 19.1213L16.9974 17M16.9974 17L14.876 14.8787\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6.5 17.5L17.5 6.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18.9919 10.5H19.0015\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10.9919 19H11.0015\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13L13 5\"/></svg>';\r\nexport const IconReplace: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M11.5 17.5L5 11M5 11V15.5M5 11H9.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12.5 6.5L19 13M19 13V8.5M19 13H14.5\"/></svg>';\r\nexport const IconSave: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M15.078 5.62637L15.6153 4.78296L15.078 5.62637C15.4261 5.84808 15.7393 6.15354 16.5711 6.98528L17.2782 6.27817L16.5711 6.98528L17.5251 7.93934C17.8347 8.2489 17.9496 8.36494 18.0489 8.48177C18.5907 9.11982 18.9188 9.91178 18.9868 10.7461C18.9992 10.8989 19 11.0622 19 11.5V12C19 13.4166 18.9992 14.419 18.9352 15.2026C18.8721 15.9745 18.7527 16.4457 18.564 16.816C18.1805 17.5686 17.5686 18.1805 16.816 18.564C16.4457 18.7527 15.9745 18.8721 15.2026 18.9352C14.419 18.9992 13.4166 19 12 19C10.5834 19 9.58104 18.9992 8.79744 18.9352C8.02552 18.8721 7.55435 18.7527 7.18404 18.564C6.43139 18.1805 5.81947 17.5686 5.43597 16.816C5.24729 16.4457 5.12787 15.9745 5.0648 15.2026C5.00078 14.419 5 13.4166 5 12V11.7782C5 10.4673 5.00067 9.53987 5.05572 8.81299C5.10998 8.09655 5.21284 7.65673 5.37487 7.3093C5.77229 6.45718 6.45718 5.77229 7.3093 5.37487C7.65673 5.21284 8.09655 5.10998 8.81299 5.05572C9.53986 5.00067 10.4673 5 11.7782 5C12.9544 5 13.3919 5.00552 13.7948 5.09484C14.2503 5.19583 14.6846 5.37572 15.078 5.62637Z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 15C13.1046 15 14 14.1046 14 13C14 11.8954 13.1046 11 12 11C10.8954 11 10 11.8954 10 13C10 14.1046 10.8954 15 12 15Z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14 5.5V7C14 7.55228 13.5523 8 13 8H11C10.4477 8 10 7.55228 10 7V5.2\"/></svg>';\r\nexport const IconSearch: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><circle cx=\"10.5\" cy=\"10.5\" r=\"5.5\" stroke=\"currentColor\" stroke-width=\"2\"/><line x1=\"15.4142\" x2=\"19\" y1=\"15\" y2=\"18.5858\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/></svg>';\r\nexport const IconStar: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M11.8197 6.04369C11.8924 5.8925 12.1076 5.8925 12.1803 6.04369L13.9776 9.78496C14.0068 9.84564 14.0645 9.88759 14.1312 9.89657L18.2448 10.4498C18.411 10.4722 18.4776 10.6769 18.3562 10.7927L15.3535 13.6582C15.3048 13.7047 15.2827 13.7726 15.2948 13.8388L16.0398 17.922C16.0699 18.087 15.8957 18.2136 15.7481 18.1339L12 16.1124L8.25192 18.1339C8.10429 18.2136 7.93012 18.087 7.96022 17.922L8.7052 13.8388C8.71728 13.7726 8.69523 13.7047 8.64652 13.6582L5.64378 10.7927C5.52244 10.6769 5.58896 10.4722 5.7552 10.4498L9.86876 9.89657C9.93549 9.88759 9.99322 9.84564 10.0224 9.78496L11.8197 6.04369Z\"/></svg>';\r\nexport const IconStretch: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M17 9L20 12L17 15\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14 12H20\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 9L4 12L7 15\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 12H10\"/></svg>';\r\nexport const IconStrikethrough: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.5 8.50001C13.5 7 10.935 6.66476 9.75315 7.79706C9.27092 8.25909 9 8.88574 9 9.53915C9 10.1926 9.27092 10.8192 9.75315 11.2812C10.9835 12.46 13.0165 11.5457 14.2468 12.7244C14.7291 13.1865 15 13.8131 15 14.4665C15 15.1199 14.7291 15.7466 14.2468 16.2086C12.8659 17.5317 10 17.5 9 16\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 12H18\"/></svg>';\r\nexport const IconTableWithHeadings: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5 10H19\"/><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/></svg>';\r\nexport const IconTableWithoutHeadings: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M10 5V18.5\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M14 5V18.5\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5 10H19\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5 14H19\"/><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/></svg>';\r\nexport const IconTable: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M10 5V18.5\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5 10H19\"/><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/></svg>';\r\nexport const IconText: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M8 9V7.2C8 7.08954 8.08954 7 8.2 7L12 7M16 9V7.2C16 7.08954 15.9105 7 15.8 7L12 7M12 7L12 17M12 17H10M12 17H14\"/></svg>';\r\nexport const IconTranslate: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7 17C8 14.5 12 12 13 9\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M8.5 11C8.5 11 10 14 12.5 15\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7.7H16M11 7.7V5.7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M14.5 18L15.2143 16M15.2143 16L16.9159 11.2354C16.9663 11.0942 17.1001 11 17.25 11C17.3999 11 17.5337 11.0942 17.5841 11.2354L19.2857 16M15.2143 16H19.2857M20 18L19.2857 16\"/></svg>';\r\nexport const IconTrash: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18.1328 7.7234C18.423 7.7634 18.7115 7.80571 19 7.85109M18.1328 7.7234L17.2267 17.4023C17.1897 17.8371 16.973 18.2432 16.62 18.5394C16.267 18.8356 15.8037 19.0001 15.3227 19H8.67733C8.19632 19.0001 7.73299 18.8356 7.37998 18.5394C7.02698 18.2432 6.81032 17.8371 6.77333 17.4023L5.86715 7.7234M18.1328 7.7234C17.1536 7.58919 16.1693 7.48733 15.1818 7.41803M5.86715 7.7234C5.57697 7.76263 5.28848 7.80494 5 7.85032M5.86715 7.7234C6.84642 7.58919 7.83074 7.48733 8.81818 7.41803M15.1818 7.41803C13.0638 7.26963 10.9362 7.26963 8.81818 7.41803M15.1818 7.41803C15.1818 5.30368 13.7266 4.34834 12 4.34834C10.2734 4.34834 8.81818 5.43945 8.81818 7.41803\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10.5 15.5L10 11\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14 11L13.5 15.5\"/></svg>';\r\nexport const IconTwitter: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16.7893 7.87697C17.5 8 18.5 8 18.5 8C18.5 8 17.5 9.5 17.5 10C18.5 18.5 11.5 20.5 5.5 16.5C6.99996 16.6712 8.04617 16.5163 9.25234 15.6024C7.99546 15.58 5.36548 13.6033 5 12.5C6.5 13 8 12 8 12C6.52134 11.0446 4.93005 9.24114 5.97461 7.50832C7.39125 9.18838 9.50766 10.2939 11.8948 10.4097C11.2198 7.60755 14.9218 5.95341 16.7893 7.87697Z\"/></svg>';\r\nexport const IconUnderline: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 7.5V11.5C9 12.2956 9.31607 13.0587 9.87868 13.6213C10.4413 14.1839 11.2044 14.5 12 14.5C12.7956 14.5 13.5587 14.1839 14.1213 13.6213C14.6839 13.0587 15 12.2956 15 11.5V7.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7.71429 18H16.2857\"/></svg>';\r\nexport const IconUndo: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.33333 13.6667L6 10.3333L9.33333 7M6 10.3333H15.1667C16.0507 10.3333 16.8986 10.6845 17.5237 11.3096C18.1488 11.9348 18.5 12.7826 18.5 13.6667C18.5 14.5507 18.1488 15.3986 17.5237 16.0237C16.8986 16.6488 16.0507 17 15.1667 17H14.3333\"/></svg>';\r\nexport const IconUnlink: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M15.7795 11.5C15.7795 11.5 16.053 11.1962 16.5497 10.6722C17.4442 9.72856 17.4701 8.2475 16.5781 7.30145V7.30145C15.6482 6.31522 14.0873 6.29227 13.1288 7.25073L11.8796 8.49999\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M8.24517 12.3883C8.24517 12.3883 7.97171 12.6922 7.47504 13.2161C6.58051 14.1598 6.55467 15.6408 7.44666 16.5869V16.5869C8.37653 17.5731 9.93744 17.5961 10.8959 16.6376L12.1452 15.3883\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M17.7802 15.1032L16.597 14.9422C16.0109 14.8624 15.4841 15.3059 15.4627 15.8969L15.4199 17.0818\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6.39064 9.03238L7.58432 9.06668C8.17551 9.08366 8.6522 8.58665 8.61056 7.99669L8.5271 6.81397\"/><line x1=\"12.1142\" x2=\"11.7\" y1=\"12.2\" y2=\"11.7858\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/></svg>';\r\nexport const IconUser: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M12 10C12.7145 10 13.239 9.56559 13.5392 9.11536C13.844 8.65814 14 8.0841 14 7.5C14 6.9159 13.844 6.34186 13.5392 5.88464C13.239 5.43441 12.7145 5 12 5C11.2855 5 10.761 5.43441 10.4608 5.88464C10.156 6.34186 10 6.9159 10 7.5C10 8.0841 10.156 8.65814 10.4608 9.11536C10.761 9.56559 11.2855 10 12 10Z\"/><ellipse cx=\"12\" cy=\"16\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"3\" ry=\"5\" transform=\"rotate(-90 12 16)\"/></svg>';\r\nexport const IconUsersGroup: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M10 10C10.7145 10 11.239 9.56559 11.5392 9.11536C11.844 8.65814 12 8.0841 12 7.5C12 6.9159 11.844 6.34186 11.5392 5.88464C11.239 5.43441 10.7145 5 10 5C9.28547 5 8.761 5.43441 8.46084 5.88464C8.15603 6.34186 8 6.9159 8 7.5C8 8.0841 8.15603 8.65814 8.46084 9.11536C8.761 9.56559 9.28547 10 10 10Z\"/><ellipse cx=\"10\" cy=\"16\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"3\" ry=\"5\" transform=\"rotate(-90 10 16)\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M15.5555 10.2222C16.5374 10.2222 17.3333 9.42629 17.3333 8.44445C17.3333 7.46261 16.5374 6.66667 15.5555 6.66667\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M17.5 13C21 14.5 20.5 18 18 18.5\"/></svg>';\r\nexport const IconWarning: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/><line x1=\"12\" x2=\"12\" y1=\"9\" y2=\"12\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12 15.02V15.01\"/></svg>';\r\n\r\nexport const IconToolboxAlert: string = '<?xml version=\"1.0\" standalone=\"no\"?><!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"><svg t=\"1763693072662\" class=\"icon\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"2633\" id=\"mx_n_1763693072663\" width=\"24\" height=\"24\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><path d=\"M83.2 147.2V448c0 25.6 19.2 44.8 44.8 44.8h768c25.6 0 44.8-19.2 44.8-44.8V147.2c0-25.6-19.2-44.8-44.8-44.8H128c-25.6 6.4-44.8 25.6-44.8 44.8z m89.6 256V192h684.8v211.2H172.8zM810.24 642.56c0-25.6-19.2-44.8-44.8-44.8h-640c-25.6 0-44.8 19.2-44.8 44.8 0 25.6 19.2 44.8 44.8 44.8h640c25.6 6.4 44.8-12.8 44.8-44.8zM554.56 866.24c0-25.6-19.2-44.8-44.8-44.8h-384c-25.6 0-44.8 19.2-44.8 44.8 0 25.6 19.2 44.8 44.8 44.8h384c25.6 6.4 44.8-12.8 44.8-44.8z\" fill=\"#262626\" p-id=\"2634\"></path></svg>';\r\n\r\nexport const IconCode: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 17C7 17 7 15.2536 7 13.5L5.5 12L7 10.5C7 8.74644 7 7 9 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 17C17 17 17 15.2536 17 13.5L18.5 12L17 10.5C17 8.74644 17 7 15 7\"/></svg>';\r\n\r\nexport const IconIndentLeft: string = '<svg t=\"1763708081701\" class=\"icon\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"2604\" width=\"24\" height=\"24\"><path d=\"M469.3330000000001 725.333H896V640H469.3330000000001v85.333zM128 512l170.667 170.667V341.3330000000001L128 512z m0 384h768v-85.333H128V896z m0-768v85.333h768V128H128z m341.333 256H896v-85.333H469.3330000000001V384z m0 170.667H896v-85.334H469.3330000000001v85.334z\" p-id=\"2605\" fill=\"#000000\"></path></svg>';\r\nexport const IconIndentRight: string = '<svg t=\"1763708124227\" class=\"icon\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"2788\" width=\"24\" height=\"24\"><path d=\"M128 896h768v-85.333H128V896z m0-554.667v341.334L298.667 512 128 341.333z m341.333 384H896V640H469.333v85.333zM128 128v85.333h768V128H128z m341.333 256H896v-85.333H469.333V384z m0 170.667H896v-85.334H469.333v85.334z\" p-id=\"2789\" fill=\"#000000\"></path></svg>';\r\n\r\n\r\nexport const IconNumber = '<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 14.2L10 7.4135C10 7.32872 9.90111 7.28241 9.83598 7.33668L7 9.7\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M13.2087 14.2H13.2\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/></svg>';\r\nexport const IconLowerRoman = '<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13.2087 14.2H13.2\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M10 14.2L10 9.5\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M10 7.01L10 7\" stroke=\"black\" stroke-width=\"1.8\" stroke-linecap=\"round\"/></svg>';\r\nexport const IconUpperRoman = '<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13.2087 14.2H13.2\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M10 14.2L10 7.2\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/></svg>';\r\nexport const IconUpperAlpha = '<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M16.0087 14.2H16\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M7 14.2L7.78865 12M13 14.2L12.1377 12M7.78865 12C7.78865 12 9.68362 7 10 7C10.3065 7 12.1377 12 12.1377 12M7.78865 12L12.1377 12\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/></svg>';\r\nexport const IconLowerAlpha = '<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M14.2087 14.2H14.2\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M11.5 14.5C11.5 14.5 11 13.281 11 12.5M7 9.5C7 9.5 7.5 8.5 9 8.5C10.5 8.5 11 9.5 11 10.5L11 11.5M11 11.5L11 12.5M11 11.5C11 11.5 7 11 7 13C7 15.3031 11 15 11 12.5\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/></svg>';\r\nexport const IconStartWith = '<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8 14.2L8 7.4135C8 7.32872 7.90111 7.28241 7.83598 7.33668L5 9.7\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M14 13L16.4167 10.7778M16.4167 10.7778L14 8.5M16.4167 10.7778H11.6562\" stroke=\"black\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>';\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\n\r\n\r\nimport { API, PasteEvent } from '@ebl-vue/editorjs';\r\nimport type { HeaderData, HeaderConfig, Level } from './types';\r\nimport type { BlockTool,BlockToolConstructorOptions } from '@ebl-vue/editorjs';\r\n\r\nimport { IconH1 } from '../../icons';\r\n\r\n\r\n\r\n/**\r\n * Header block for the Editor.js.\r\n *\r\n * @author CodeX (team@ifmo.su)\r\n * @copyright CodeX 2018\r\n * @license MIT\r\n * @version 2.0.0\r\n */\r\nexport default class H1 implements BlockTool {\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {{data: HeaderData, config: HeaderConfig, api: object}}\r\n * data — previously saved data\r\n * config - user config for Tool\r\n * api - Editor.js API\r\n * readOnly - read only mode flag\r\n */\r\n /**\r\n * Editor.js API\r\n * @private\r\n */\r\n private api: API;\r\n /**\r\n * Read-only mode flag\r\n * @private\r\n */\r\n private readOnly: boolean;\r\n /**\r\n * Tool's settings passed from Editor\r\n * @private\r\n */\r\n private _settings: HeaderConfig;\r\n /**\r\n * Block's data\r\n * @private\r\n */\r\n private _data: HeaderData;\r\n /**\r\n * Main Block wrapper\r\n * @private\r\n */\r\n private _element: HTMLHeadingElement;\r\n\r\n \r\n\r\n constructor({ data, config, api, readOnly }: BlockToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n /**\r\n * Tool's settings passed from Editor\r\n *\r\n * @type {HeaderConfig}\r\n * @private\r\n */\r\n this._settings={placeholder:\"H1\"};\r\n\r\n /**\r\n * Block's data\r\n *\r\n * @type {HeaderData}\r\n * @private\r\n */\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * Main Block wrapper\r\n *\r\n * @type {HTMLElement}\r\n * @private\r\n */\r\n this._element = this.getTag();\r\n\r\n }\r\n /**\r\n * Styles\r\n */\r\n private get _CSS() {\r\n return {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-header',\r\n };\r\n }\r\n\r\n /**\r\n * Check if data is valid\r\n * \r\n * @param {any} data - data to check\r\n * @returns {data is HeaderData}\r\n * @private\r\n */\r\n isHeaderData(data: any): data is HeaderData {\r\n return (data as HeaderData).text !== undefined;\r\n }\r\n\r\n /**\r\n * Normalize input data\r\n *\r\n * @param {HeaderData} data - saved data to process\r\n *\r\n * @returns {HeaderData}\r\n * @private\r\n */\r\n normalizeData(data: HeaderData | {}): HeaderData {\r\n const newData: HeaderData = { text: '', level: this.defaultLevel.number };\r\n\r\n if (this.isHeaderData(data)) {\r\n newData.text = data.text || '';\r\n \r\n if (data.level !== undefined && !isNaN(parseInt(data.level.toString()))) {\r\n newData.level = parseInt(data.level.toString());\r\n }\r\n }\r\n\r\n return newData;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLHeadingElement}\r\n * @public\r\n */\r\n render(): HTMLHeadingElement {\r\n return this._element;\r\n }\r\n\r\n\r\n /**\r\n * Callback for Block's settings buttons\r\n *\r\n * @param {number} level - level to set\r\n */\r\n setLevel(level: number): void {\r\n this.data = {\r\n level: level,\r\n text: this.data.text,\r\n };\r\n }\r\n\r\n /**\r\n * Method that specified how to merge two Text blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * @param {HeaderData} data - saved data to merger with current block\r\n * @public\r\n */\r\n merge(data: HeaderData): void {\r\n this._element.insertAdjacentHTML('beforeend', data.text)\r\n }\r\n\r\n /**\r\n * Validate Text block data:\r\n * - check for emptiness\r\n *\r\n * @param {HeaderData} blockData — data received after saving\r\n * @returns {boolean} false if saved data is not correct, otherwise true\r\n * @public\r\n */\r\n validate(blockData: HeaderData): boolean {\r\n return blockData.text.trim() !== '';\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n *\r\n * @param {HTMLHeadingElement} toolsContent - Text tools rendered view\r\n * @returns {HeaderData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLHeadingElement): HeaderData {\r\n return {\r\n text: toolsContent.innerHTML,\r\n level: this.defaultLevel.number,\r\n };\r\n }\r\n\r\n /**\r\n * Allow Header to be converted to/from other blocks\r\n */\r\n static get conversionConfig() {\r\n return {\r\n export: 'text', // use 'text' property for other blocks\r\n import: 'text', // fill 'text' property from other block's export string\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer Rules\r\n */\r\n static get sanitize() {\r\n return {\r\n level: false,\r\n text: {},\r\n };\r\n }\r\n\r\n /**\r\n * Returns true to notify core that read-only is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get current Tools`s data\r\n *\r\n * @returns {HeaderData} Current data\r\n * @private\r\n */\r\n get data(): HeaderData {\r\n this._data.text = this._element.innerHTML;\r\n this._data.level = this.defaultLevel.number;\r\n \r\n return this._data;\r\n }\r\n\r\n /**\r\n * Store data in plugin:\r\n * - at the this._data property\r\n * - at the HTML\r\n *\r\n * @param {HeaderData} data — data to set\r\n * @private\r\n */\r\n set data(data: HeaderData) {\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * If level is set and block in DOM\r\n * then replace it to a new block\r\n */\r\n if (data.level !== undefined && this._element.parentNode) {\r\n /**\r\n * Create a new tag\r\n *\r\n * @type {HTMLHeadingElement}\r\n */\r\n const newHeader = this.getTag();\r\n\r\n /**\r\n * Save Block's content\r\n */\r\n newHeader.innerHTML = this._element.innerHTML;\r\n\r\n /**\r\n * Replace blocks\r\n */\r\n this._element.parentNode.replaceChild(newHeader, this._element);\r\n\r\n /**\r\n * Save new block to private variable\r\n *\r\n * @type {HTMLHeadingElement}\r\n * @private\r\n */\r\n this._element = newHeader;\r\n }\r\n\r\n /**\r\n * If data.text was passed then update block's content\r\n */\r\n if (data.text !== undefined) {\r\n this._element.innerHTML = this._data.text || '';\r\n }\r\n }\r\n\r\n /**\r\n * Get tag for target level\r\n * By default returns second-leveled header\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n getTag(): HTMLHeadingElement {\r\n const tag = this.createHeadingElement();\r\n this.setElementContent(tag);\r\n this.addStylesToElement(tag);\r\n this.setEditability(tag);\r\n this.addPlaceholder(tag);\r\n return tag;\r\n }\r\n\r\n /**\r\n * 创建标题元素\r\n * @returns {HTMLHeadingElement} 创建的HTML标题元素\r\n * @private\r\n */\r\n private createHeadingElement(): HTMLHeadingElement {\r\n return document.createElement(this.defaultLevel.tag) as HTMLHeadingElement;\r\n }\r\n\r\n /**\r\n * 设置元素内容\r\n * @param {HTMLHeadingElement} element - 要设置内容的HTML标题元素\r\n * @private\r\n */\r\n private setElementContent(element: HTMLHeadingElement): void {\r\n element.innerHTML = this._data.text || '';\r\n }\r\n\r\n /**\r\n * 为元素添加样式类\r\n * @param {HTMLHeadingElement} element - 要添加样式的HTML标题元素\r\n * @private\r\n */\r\n private addStylesToElement(element: HTMLHeadingElement): void {\r\n element.classList.add(this._CSS.wrapper);\r\n }\r\n\r\n /**\r\n * 设置元素可编辑属性\r\n * @param {HTMLHeadingElement} element - 要设置编辑属性的HTML标题元素\r\n * @private\r\n */\r\n private setEditability(element: HTMLHeadingElement): void {\r\n element.contentEditable = this.readOnly ? 'false' : 'true';\r\n }\r\n\r\n /**\r\n * 为元素添加占位符文本\r\n * @param {HTMLHeadingElement} element - 要添加占位符的HTML标题元素\r\n * @private\r\n */\r\n private addPlaceholder(element: HTMLHeadingElement): void {\r\n element.dataset.placeholder = this.api.i18n.t(this._settings.placeholder || '');\r\n }\r\n\r\n\r\n\r\n /**\r\n * Return default level\r\n *\r\n * @returns {level}\r\n */\r\n get defaultLevel(): Level {\r\n return {\r\n number: 1,\r\n tag: 'H1',\r\n svg: IconH1,\r\n };\r\n }\r\n\r\n\r\n\r\n\r\n /**\r\n * Handle H1-H6 tags on paste to substitute it with header Tool\r\n *\r\n * @param {PasteEvent} event - event with pasted content\r\n */\r\n onPaste(event: PasteEvent): void {\r\n const detail = event.detail;\r\n\r\n if ('data' in detail) {\r\n const content = detail.data as HTMLElement;\r\n this.data = {\r\n level: 1,\r\n text: content.innerHTML,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Used by Editor.js paste handling API.\r\n * Provides configuration to handle H1-H6 tags.\r\n *\r\n * @returns {{handler: (function(HTMLElement): {text: string}), tags: string[]}}\r\n */\r\n static get pasteConfig() {\r\n return {\r\n tags: ['H1'],\r\n };\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @returns {{icon: string, title: string}}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: IconH1,\r\n title: 'H1'\r\n };\r\n }\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\n\r\n\r\nimport { API, PasteEvent } from '@ebl-vue/editorjs';\r\nimport type { HeaderData, HeaderConfig, Level } from './types';\r\nimport type { BlockTool, BlockToolConstructorOptions } from '@ebl-vue/editorjs';\r\nimport { IconH2 } from '../../icons';\r\n\r\n\r\n\r\n/**\r\n * Header block for the Editor.js.\r\n *\r\n * @author CodeX (team@ifmo.su)\r\n * @copyright CodeX 2018\r\n * @license MIT\r\n * @version 2.0.0\r\n */\r\nexport default class H2 implements BlockTool {\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {{data: HeaderData, config: HeaderConfig, api: object}}\r\n * data — previously saved data\r\n * config - user config for Tool\r\n * api - Editor.js API\r\n * readOnly - read only mode flag\r\n */\r\n /**\r\n * Editor.js API\r\n * @private\r\n */\r\n private api: API;\r\n /**\r\n * Read-only mode flag\r\n * @private\r\n */\r\n private readOnly: boolean;\r\n /**\r\n * Tool's settings passed from Editor\r\n * @private\r\n */\r\n private _settings: HeaderConfig;\r\n /**\r\n * Block's data\r\n * @private\r\n */\r\n private _data: HeaderData;\r\n /**\r\n * Main Block wrapper\r\n * @private\r\n */\r\n private _element: HTMLHeadingElement;\r\n\r\n \r\n\r\n constructor({ data, config, api, readOnly }: BlockToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n /**\r\n * Tool's settings passed from Editor\r\n *\r\n * @type {HeaderConfig}\r\n * @private\r\n */\r\n this._settings={placeholder:\"H2\"};\r\n\r\n /**\r\n * Block's data\r\n *\r\n * @type {HeaderData}\r\n * @private\r\n */\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * Main Block wrapper\r\n *\r\n * @type {HTMLElement}\r\n * @private\r\n */\r\n this._element = this.getTag();\r\n }\r\n /**\r\n * Styles\r\n */\r\n private get _CSS() {\r\n return {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-header',\r\n };\r\n }\r\n\r\n /**\r\n * Check if data is valid\r\n * \r\n * @param {any} data - data to check\r\n * @returns {data is HeaderData}\r\n * @private\r\n */\r\n isHeaderData(data: any): data is HeaderData {\r\n return (data as HeaderData).text !== undefined;\r\n }\r\n\r\n /**\r\n * Normalize input data\r\n *\r\n * @param {HeaderData} data - saved data to process\r\n *\r\n * @returns {HeaderData}\r\n * @private\r\n */\r\n normalizeData(data: HeaderData | {}): HeaderData {\r\n const newData: HeaderData = { text: '', level: this.defaultLevel.number };\r\n\r\n if (this.isHeaderData(data)) {\r\n newData.text = data.text || '';\r\n \r\n if (data.level !== undefined && !isNaN(parseInt(data.level.toString()))) {\r\n newData.level = parseInt(data.level.toString());\r\n }\r\n }\r\n\r\n return newData;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLHeadingElement}\r\n * @public\r\n */\r\n render(): HTMLHeadingElement {\r\n return this._element;\r\n }\r\n\r\n\r\n /**\r\n * Callback for Block's settings buttons\r\n *\r\n * @param {number} level - level to set\r\n */\r\n setLevel(level: number): void {\r\n this.data = {\r\n level: level,\r\n text: this.data.text,\r\n };\r\n }\r\n\r\n /**\r\n * Method that specified how to merge two Text blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * @param {HeaderData} data - saved data to merger with current block\r\n * @public\r\n */\r\n merge(data: HeaderData): void {\r\n this._element.insertAdjacentHTML('beforeend', data.text)\r\n }\r\n\r\n /**\r\n * Validate Text block data:\r\n * - check for emptiness\r\n *\r\n * @param {HeaderData} blockData — data received after saving\r\n * @returns {boolean} false if saved data is not correct, otherwise true\r\n * @public\r\n */\r\n validate(blockData: HeaderData): boolean {\r\n return blockData.text.trim() !== '';\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n *\r\n * @param {HTMLHeadingElement} toolsContent - Text tools rendered view\r\n * @returns {HeaderData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLHeadingElement): HeaderData {\r\n return {\r\n text: toolsContent.innerHTML,\r\n level: this.defaultLevel.number,\r\n };\r\n }\r\n\r\n /**\r\n * Allow Header to be converted to/from other blocks\r\n */\r\n static get conversionConfig() {\r\n return {\r\n export: 'text', // use 'text' property for other blocks\r\n import: 'text', // fill 'text' property from other block's export string\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer Rules\r\n */\r\n static get sanitize() {\r\n return {\r\n level: false,\r\n text: {},\r\n };\r\n }\r\n\r\n /**\r\n * Returns true to notify core that read-only is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get current Tools`s data\r\n *\r\n * @returns {HeaderData} Current data\r\n * @private\r\n */\r\n get data(): HeaderData {\r\n this._data.text = this._element.innerHTML;\r\n this._data.level = this.defaultLevel.number;\r\n \r\n return this._data;\r\n }\r\n\r\n /**\r\n * Store data in plugin:\r\n * - at the this._data property\r\n * - at the HTML\r\n *\r\n * @param {HeaderData} data — data to set\r\n * @private\r\n */\r\n set data(data: HeaderData) {\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * If level is set and block in DOM\r\n * then replace it to a new block\r\n */\r\n if (data.level !== undefined && this._element.parentNode) {\r\n /**\r\n * Create a new tag\r\n *\r\n * @type {HTMLHeadingElement}\r\n */\r\n const newHeader = this.getTag();\r\n\r\n /**\r\n * Save Block's content\r\n */\r\n newHeader.innerHTML = this._element.innerHTML;\r\n\r\n /**\r\n * Replace blocks\r\n */\r\n this._element.parentNode.replaceChild(newHeader, this._element);\r\n\r\n /**\r\n * Save new block to private variable\r\n *\r\n * @type {HTMLHeadingElement}\r\n * @private\r\n */\r\n this._element = newHeader;\r\n }\r\n\r\n /**\r\n * If data.text was passed then update block's content\r\n */\r\n if (data.text !== undefined) {\r\n this._element.innerHTML = this._data.text || '';\r\n }\r\n }\r\n\r\n /**\r\n * Get tag for target level\r\n * By default returns second-leveled header\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n getTag(): HTMLHeadingElement {\r\n const tag = this.createHeadingElement();\r\n this.setElementContent(tag);\r\n this.addStylesToElement(tag);\r\n this.setEditability(tag);\r\n this.addPlaceholder(tag);\r\n return tag;\r\n }\r\n\r\n /**\r\n * 创建标题元素\r\n * @returns {HTMLHeadingElement} 创建的HTML标题元素\r\n * @private\r\n */\r\n private createHeadingElement(): HTMLHeadingElement {\r\n return document.createElement(this.defaultLevel.tag) as HTMLHeadingElement;\r\n }\r\n\r\n /**\r\n * 设置元素内容\r\n * @param {HTMLHeadingElement} element - 要设置内容的HTML标题元素\r\n * @private\r\n */\r\n private setElementContent(element: HTMLHeadingElement): void {\r\n element.innerHTML = this._data.text || '';\r\n }\r\n\r\n /**\r\n * 为元素添加样式类\r\n * @param {HTMLHeadingElement} element - 要添加样式的HTML标题元素\r\n * @private\r\n */\r\n private addStylesToElement(element: HTMLHeadingElement): void {\r\n element.classList.add(this._CSS.wrapper);\r\n }\r\n\r\n /**\r\n * 设置元素可编辑属性\r\n * @param {HTMLHeadingElement} element - 要设置编辑属性的HTML标题元素\r\n * @private\r\n */\r\n private setEditability(element: HTMLHeadingElement): void {\r\n element.contentEditable = this.readOnly ? 'false' : 'true';\r\n }\r\n\r\n /**\r\n * 为元素添加占位符文本\r\n * @param {HTMLHeadingElement} element - 要添加占位符的HTML标题元素\r\n * @private\r\n */\r\n private addPlaceholder(element: HTMLHeadingElement): void {\r\n element.dataset.placeholder = this.api.i18n.t(this._settings.placeholder || '');\r\n }\r\n\r\n\r\n\r\n /**\r\n * Return default level\r\n *\r\n * @returns {level}\r\n */\r\n get defaultLevel(): Level {\r\n return {\r\n number: 2,\r\n tag: 'H2',\r\n svg: IconH2,\r\n };\r\n }\r\n\r\n\r\n\r\n\r\n /**\r\n * Handle H1-H6 tags on paste to substitute it with header Tool\r\n *\r\n * @param {PasteEvent} event - event with pasted content\r\n */\r\n onPaste(event: PasteEvent): void {\r\n const detail = event.detail;\r\n\r\n if ('data' in detail) {\r\n const content = detail.data as HTMLElement;\r\n this.data = {\r\n level: 2,\r\n text: content.innerHTML,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Used by Editor.js paste handling API.\r\n * Provides configuration to handle H1-H6 tags.\r\n *\r\n * @returns {{handler: (function(HTMLElement): {text: string}), tags: string[]}}\r\n */\r\n static get pasteConfig() {\r\n return {\r\n tags: ['H2'],\r\n };\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @returns {{icon: string, title: string}}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: IconH2,\r\n title: 'H2',\r\n };\r\n }\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\n\r\n\r\nimport { API, PasteEvent } from '@ebl-vue/editorjs';\r\nimport type { HeaderData, HeaderConfig, Level } from './types';\r\nimport type { BlockTool, BlockToolConstructorOptions } from '@ebl-vue/editorjs';\r\n\r\nimport { IconH3 } from '../../icons';\r\n\r\n\r\n\r\n/**\r\n * Header block for the Editor.js.\r\n *\r\n * @author CodeX (team@ifmo.su)\r\n * @copyright CodeX 2018\r\n * @license MIT\r\n * @version 2.0.0\r\n */\r\nexport default class H3 implements BlockTool {\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {{data: HeaderData, config: HeaderConfig, api: object}}\r\n * data — previously saved data\r\n * config - user config for Tool\r\n * api - Editor.js API\r\n * readOnly - read only mode flag\r\n */\r\n /**\r\n * Editor.js API\r\n * @private\r\n */\r\n private api: API;\r\n /**\r\n * Read-only mode flag\r\n * @private\r\n */\r\n private readOnly: boolean;\r\n /**\r\n * Tool's settings passed from Editor\r\n * @private\r\n */\r\n private _settings: HeaderConfig;\r\n /**\r\n * Block's data\r\n * @private\r\n */\r\n private _data: HeaderData;\r\n /**\r\n * Main Block wrapper\r\n * @private\r\n */\r\n private _element: HTMLHeadingElement;\r\n\r\n \r\n\r\n constructor({ data, config, api, readOnly }: BlockToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n /**\r\n * Tool's settings passed from Editor\r\n *\r\n * @type {HeaderConfig}\r\n * @private\r\n */\r\n this._settings={placeholder:\"H3\"};\r\n\r\n /**\r\n * Block's data\r\n *\r\n * @type {HeaderData}\r\n * @private\r\n */\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * Main Block wrapper\r\n *\r\n * @type {HTMLElement}\r\n * @private\r\n */\r\n this._element = this.getTag();\r\n }\r\n /**\r\n * Styles\r\n */\r\n private get _CSS() {\r\n return {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-header',\r\n };\r\n }\r\n\r\n /**\r\n * Check if data is valid\r\n * \r\n * @param {any} data - data to check\r\n * @returns {data is HeaderData}\r\n * @private\r\n */\r\n isHeaderData(data: any): data is HeaderData {\r\n return (data as HeaderData).text !== undefined;\r\n }\r\n\r\n /**\r\n * Normalize input data\r\n *\r\n * @param {HeaderData} data - saved data to process\r\n *\r\n * @returns {HeaderData}\r\n * @private\r\n */\r\n normalizeData(data: HeaderData | {}): HeaderData {\r\n const newData: HeaderData = { text: '', level: this.defaultLevel.number };\r\n\r\n if (this.isHeaderData(data)) {\r\n newData.text = data.text || '';\r\n \r\n if (data.level !== undefined && !isNaN(parseInt(data.level.toString()))) {\r\n newData.level = parseInt(data.level.toString());\r\n }\r\n }\r\n\r\n return newData;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLHeadingElement}\r\n * @public\r\n */\r\n render(): HTMLHeadingElement {\r\n return this._element;\r\n }\r\n\r\n\r\n /**\r\n * Callback for Block's settings buttons\r\n *\r\n * @param {number} level - level to set\r\n */\r\n setLevel(level: number): void {\r\n this.data = {\r\n level: level,\r\n text: this.data.text,\r\n };\r\n }\r\n\r\n /**\r\n * Method that specified how to merge two Text blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * @param {HeaderData} data - saved data to merger with current block\r\n * @public\r\n */\r\n merge(data: HeaderData): void {\r\n this._element.insertAdjacentHTML('beforeend', data.text)\r\n }\r\n\r\n /**\r\n * Validate Text block data:\r\n * - check for emptiness\r\n *\r\n * @param {HeaderData} blockData — data received after saving\r\n * @returns {boolean} false if saved data is not correct, otherwise true\r\n * @public\r\n */\r\n validate(blockData: HeaderData): boolean {\r\n return blockData.text.trim() !== '';\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n *\r\n * @param {HTMLHeadingElement} toolsContent - Text tools rendered view\r\n * @returns {HeaderData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLHeadingElement): HeaderData {\r\n return {\r\n text: toolsContent.innerHTML,\r\n level: this.defaultLevel.number,\r\n };\r\n }\r\n\r\n /**\r\n * Allow Header to be converted to/from other blocks\r\n */\r\n static get conversionConfig() {\r\n return {\r\n export: 'text', // use 'text' property for other blocks\r\n import: 'text', // fill 'text' property from other block's export string\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer Rules\r\n */\r\n static get sanitize() {\r\n return {\r\n level: false,\r\n text: {},\r\n };\r\n }\r\n\r\n /**\r\n * Returns true to notify core that read-only is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get current Tools`s data\r\n *\r\n * @returns {HeaderData} Current data\r\n * @private\r\n */\r\n get data(): HeaderData {\r\n this._data.text = this._element.innerHTML;\r\n this._data.level = this.defaultLevel.number;\r\n \r\n return this._data;\r\n }\r\n\r\n /**\r\n * Store data in plugin:\r\n * - at the this._data property\r\n * - at the HTML\r\n *\r\n * @param {HeaderData} data — data to set\r\n * @private\r\n */\r\n set data(data: HeaderData) {\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * If level is set and block in DOM\r\n * then replace it to a new block\r\n */\r\n if (data.level !== undefined && this._element.parentNode) {\r\n /**\r\n * Create a new tag\r\n *\r\n * @type {HTMLHeadingElement}\r\n */\r\n const newHeader = this.getTag();\r\n\r\n /**\r\n * Save Block's content\r\n */\r\n newHeader.innerHTML = this._element.innerHTML;\r\n\r\n /**\r\n * Replace blocks\r\n */\r\n this._element.parentNode.replaceChild(newHeader, this._element);\r\n\r\n /**\r\n * Save new block to private variable\r\n *\r\n * @type {HTMLHeadingElement}\r\n * @private\r\n */\r\n this._element = newHeader;\r\n }\r\n\r\n /**\r\n * If data.text was passed then update block's content\r\n */\r\n if (data.text !== undefined) {\r\n this._element.innerHTML = this._data.text || '';\r\n }\r\n }\r\n\r\n /**\r\n * Get tag for target level\r\n * By default returns second-leveled header\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n getTag(): HTMLHeadingElement {\r\n const tag = this.createHeadingElement();\r\n this.setElementContent(tag);\r\n this.addStylesToElement(tag);\r\n this.setEditability(tag);\r\n this.addPlaceholder(tag);\r\n return tag;\r\n }\r\n\r\n /**\r\n * 创建标题元素\r\n * @returns {HTMLHeadingElement} 创建的HTML标题元素\r\n * @private\r\n */\r\n private createHeadingElement(): HTMLHeadingElement {\r\n return document.createElement(this.defaultLevel.tag) as HTMLHeadingElement;\r\n }\r\n\r\n /**\r\n * 设置元素内容\r\n * @param {HTMLHeadingElement} element - 要设置内容的HTML标题元素\r\n * @private\r\n */\r\n private setElementContent(element: HTMLHeadingElement): void {\r\n element.innerHTML = this._data.text || '';\r\n }\r\n\r\n /**\r\n * 为元素添加样式类\r\n * @param {HTMLHeadingElement} element - 要添加样式的HTML标题元素\r\n * @private\r\n */\r\n private addStylesToElement(element: HTMLHeadingElement): void {\r\n element.classList.add(this._CSS.wrapper);\r\n }\r\n\r\n /**\r\n * 设置元素可编辑属性\r\n * @param {HTMLHeadingElement} element - 要设置编辑属性的HTML标题元素\r\n * @private\r\n */\r\n private setEditability(element: HTMLHeadingElement): void {\r\n element.contentEditable = this.readOnly ? 'false' : 'true';\r\n }\r\n\r\n /**\r\n * 为元素添加占位符文本\r\n * @param {HTMLHeadingElement} element - 要添加占位符的HTML标题元素\r\n * @private\r\n */\r\n private addPlaceholder(element: HTMLHeadingElement): void {\r\n element.dataset.placeholder = this.api.i18n.t(this._settings.placeholder || '');\r\n }\r\n\r\n\r\n\r\n /**\r\n * Return default level\r\n *\r\n * @returns {level}\r\n */\r\n get defaultLevel(): Level {\r\n return {\r\n number: 3,\r\n tag: 'H3',\r\n svg: IconH3,\r\n };\r\n }\r\n\r\n\r\n\r\n\r\n /**\r\n * Handle H1-H6 tags on paste to substitute it with header Tool\r\n *\r\n * @param {PasteEvent} event - event with pasted content\r\n */\r\n onPaste(event: PasteEvent): void {\r\n const detail = event.detail;\r\n\r\n if ('data' in detail) {\r\n const content = detail.data as HTMLElement;\r\n this.data = {\r\n level: 3,\r\n text: content.innerHTML,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Used by Editor.js paste handling API.\r\n * Provides configuration to handle H1-H6 tags.\r\n *\r\n * @returns {{handler: (function(HTMLElement): {text: string}), tags: string[]}}\r\n */\r\n static get pasteConfig() {\r\n return {\r\n tags: ['H3'],\r\n };\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @returns {{icon: string, title: string}}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: IconH3,\r\n title: 'H3',\r\n };\r\n }\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\n\r\n\r\nimport { API, PasteEvent } from '@ebl-vue/editorjs';\r\nimport type { HeaderData, HeaderConfig, Level } from './types';\r\nimport type { BlockTool, BlockToolConstructorOptions } from '@ebl-vue/editorjs';\r\n\r\n\r\n\r\nimport { IconH4 } from '../../icons';\r\n\r\n/**\r\n * Header block for the Editor.js.\r\n *\r\n * @author CodeX (team@ifmo.su)\r\n * @copyright CodeX 2018\r\n * @license MIT\r\n * @version 2.0.0\r\n */\r\nexport default class H4 implements BlockTool {\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {{data: HeaderData, config: HeaderConfig, api: object}}\r\n * data — previously saved data\r\n * config - user config for Tool\r\n * api - Editor.js API\r\n * readOnly - read only mode flag\r\n */\r\n /**\r\n * Editor.js API\r\n * @private\r\n */\r\n private api: API;\r\n /**\r\n * Read-only mode flag\r\n * @private\r\n */\r\n private readOnly: boolean;\r\n /**\r\n * Tool's settings passed from Editor\r\n * @private\r\n */\r\n private _settings: HeaderConfig;\r\n /**\r\n * Block's data\r\n * @private\r\n */\r\n private _data: HeaderData;\r\n /**\r\n * Main Block wrapper\r\n * @private\r\n */\r\n private _element: HTMLHeadingElement;\r\n\r\n \r\n\r\n constructor({ data, config, api, readOnly }: BlockToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n /**\r\n * Tool's settings passed from Editor\r\n *\r\n * @type {HeaderConfig}\r\n * @private\r\n */\r\n this._settings={placeholder:\"H4\"};\r\n\r\n /**\r\n * Block's data\r\n *\r\n * @type {HeaderData}\r\n * @private\r\n */\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * Main Block wrapper\r\n *\r\n * @type {HTMLElement}\r\n * @private\r\n */\r\n this._element = this.getTag();\r\n }\r\n /**\r\n * Styles\r\n */\r\n private get _CSS() {\r\n return {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-header',\r\n };\r\n }\r\n\r\n /**\r\n * Check if data is valid\r\n * \r\n * @param {any} data - data to check\r\n * @returns {data is HeaderData}\r\n * @private\r\n */\r\n isHeaderData(data: any): data is HeaderData {\r\n return (data as HeaderData).text !== undefined;\r\n }\r\n\r\n /**\r\n * Normalize input data\r\n *\r\n * @param {HeaderData} data - saved data to process\r\n *\r\n * @returns {HeaderData}\r\n * @private\r\n */\r\n normalizeData(data: HeaderData | {}): HeaderData {\r\n const newData: HeaderData = { text: '', level: this.defaultLevel.number };\r\n\r\n if (this.isHeaderData(data)) {\r\n newData.text = data.text || '';\r\n \r\n if (data.level !== undefined && !isNaN(parseInt(data.level.toString()))) {\r\n newData.level = parseInt(data.level.toString());\r\n }\r\n }\r\n\r\n return newData;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLHeadingElement}\r\n * @public\r\n */\r\n render(): HTMLHeadingElement {\r\n return this._element;\r\n }\r\n\r\n\r\n /**\r\n * Callback for Block's settings buttons\r\n *\r\n * @param {number} level - level to set\r\n */\r\n setLevel(level: number): void {\r\n this.data = {\r\n level: level,\r\n text: this.data.text,\r\n };\r\n }\r\n\r\n /**\r\n * Method that specified how to merge two Text blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * @param {HeaderData} data - saved data to merger with current block\r\n * @public\r\n */\r\n merge(data: HeaderData): void {\r\n this._element.insertAdjacentHTML('beforeend', data.text)\r\n }\r\n\r\n /**\r\n * Validate Text block data:\r\n * - check for emptiness\r\n *\r\n * @param {HeaderData} blockData — data received after saving\r\n * @returns {boolean} false if saved data is not correct, otherwise true\r\n * @public\r\n */\r\n validate(blockData: HeaderData): boolean {\r\n return blockData.text.trim() !== '';\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n *\r\n * @param {HTMLHeadingElement} toolsContent - Text tools rendered view\r\n * @returns {HeaderData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLHeadingElement): HeaderData {\r\n return {\r\n text: toolsContent.innerHTML,\r\n level: this.defaultLevel.number,\r\n };\r\n }\r\n\r\n /**\r\n * Allow Header to be converted to/from other blocks\r\n */\r\n static get conversionConfig() {\r\n return {\r\n export: 'text', // use 'text' property for other blocks\r\n import: 'text', // fill 'text' property from other block's export string\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer Rules\r\n */\r\n static get sanitize() {\r\n return {\r\n level: false,\r\n text: {},\r\n };\r\n }\r\n\r\n /**\r\n * Returns true to notify core that read-only is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get current Tools`s data\r\n *\r\n * @returns {HeaderData} Current data\r\n * @private\r\n */\r\n get data(): HeaderData {\r\n this._data.text = this._element.innerHTML;\r\n this._data.level = this.defaultLevel.number;\r\n \r\n return this._data;\r\n }\r\n\r\n /**\r\n * Store data in plugin:\r\n * - at the this._data property\r\n * - at the HTML\r\n *\r\n * @param {HeaderData} data — data to set\r\n * @private\r\n */\r\n set data(data: HeaderData) {\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * If level is set and block in DOM\r\n * then replace it to a new block\r\n */\r\n if (data.level !== undefined && this._element.parentNode) {\r\n /**\r\n * Create a new tag\r\n *\r\n * @type {HTMLHeadingElement}\r\n */\r\n const newHeader = this.getTag();\r\n\r\n /**\r\n * Save Block's content\r\n */\r\n newHeader.innerHTML = this._element.innerHTML;\r\n\r\n /**\r\n * Replace blocks\r\n */\r\n this._element.parentNode.replaceChild(newHeader, this._element);\r\n\r\n /**\r\n * Save new block to private variable\r\n *\r\n * @type {HTMLHeadingElement}\r\n * @private\r\n */\r\n this._element = newHeader;\r\n }\r\n\r\n /**\r\n * If data.text was passed then update block's content\r\n */\r\n if (data.text !== undefined) {\r\n this._element.innerHTML = this._data.text || '';\r\n }\r\n }\r\n\r\n /**\r\n * Get tag for target level\r\n * By default returns second-leveled header\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n getTag(): HTMLHeadingElement {\r\n const tag = this.createHeadingElement();\r\n this.setElementContent(tag);\r\n this.addStylesToElement(tag);\r\n this.setEditability(tag);\r\n this.addPlaceholder(tag);\r\n return tag;\r\n }\r\n\r\n /**\r\n * 创建标题元素\r\n * @returns {HTMLHeadingElement} 创建的HTML标题元素\r\n * @private\r\n */\r\n private createHeadingElement(): HTMLHeadingElement {\r\n return document.createElement(this.defaultLevel.tag) as HTMLHeadingElement;\r\n }\r\n\r\n /**\r\n * 设置元素内容\r\n * @param {HTMLHeadingElement} element - 要设置内容的HTML标题元素\r\n * @private\r\n */\r\n private setElementContent(element: HTMLHeadingElement): void {\r\n element.innerHTML = this._data.text || '';\r\n }\r\n\r\n /**\r\n * 为元素添加样式类\r\n * @param {HTMLHeadingElement} element - 要添加样式的HTML标题元素\r\n * @private\r\n */\r\n private addStylesToElement(element: HTMLHeadingElement): void {\r\n element.classList.add(this._CSS.wrapper);\r\n }\r\n\r\n /**\r\n * 设置元素可编辑属性\r\n * @param {HTMLHeadingElement} element - 要设置编辑属性的HTML标题元素\r\n * @private\r\n */\r\n private setEditability(element: HTMLHeadingElement): void {\r\n element.contentEditable = this.readOnly ? 'false' : 'true';\r\n }\r\n\r\n /**\r\n * 为元素添加占位符文本\r\n * @param {HTMLHeadingElement} element - 要添加占位符的HTML标题元素\r\n * @private\r\n */\r\n private addPlaceholder(element: HTMLHeadingElement): void {\r\n element.dataset.placeholder = this.api.i18n.t(this._settings.placeholder || '');\r\n }\r\n\r\n\r\n\r\n /**\r\n * Return default level\r\n *\r\n * @returns {level}\r\n */\r\n get defaultLevel(): Level {\r\n return {\r\n number: 4,\r\n tag: 'H4',\r\n svg: IconH4,\r\n };\r\n }\r\n\r\n\r\n\r\n\r\n /**\r\n * Handle H1-H6 tags on paste to substitute it with header Tool\r\n *\r\n * @param {PasteEvent} event - event with pasted content\r\n */\r\n onPaste(event: PasteEvent): void {\r\n const detail = event.detail;\r\n\r\n if ('data' in detail) {\r\n const content = detail.data as HTMLElement;\r\n this.data = {\r\n level: 4,\r\n text: content.innerHTML,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Used by Editor.js paste handling API.\r\n * Provides configuration to handle H1-H6 tags.\r\n *\r\n * @returns {{handler: (function(HTMLElement): {text: string}), tags: string[]}}\r\n */\r\n static get pasteConfig() {\r\n return {\r\n tags: ['H4'],\r\n };\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @returns {{icon: string, title: string}}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: IconH4,\r\n title: 'H4',\r\n };\r\n }\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\n\r\n\r\nimport { API, PasteEvent } from '@ebl-vue/editorjs';\r\nimport type { HeaderData, HeaderConfig, Level } from './types';\r\nimport type { BlockTool, BlockToolConstructorOptions } from '@ebl-vue/editorjs';\r\n\r\n\r\nimport { IconH5 } from '../../icons';\r\n\r\n/**\r\n * Header block for the Editor.js.\r\n *\r\n * @author CodeX (team@ifmo.su)\r\n * @copyright CodeX 2018\r\n * @license MIT\r\n * @version 2.0.0\r\n */\r\nexport default class H5 implements BlockTool {\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {{data: HeaderData, config: HeaderConfig, api: object}}\r\n * data — previously saved data\r\n * config - user config for Tool\r\n * api - Editor.js API\r\n * readOnly - read only mode flag\r\n */\r\n /**\r\n * Editor.js API\r\n * @private\r\n */\r\n private api: API;\r\n /**\r\n * Read-only mode flag\r\n * @private\r\n */\r\n private readOnly: boolean;\r\n /**\r\n * Tool's settings passed from Editor\r\n * @private\r\n */\r\n private _settings: HeaderConfig;\r\n /**\r\n * Block's data\r\n * @private\r\n */\r\n private _data: HeaderData;\r\n /**\r\n * Main Block wrapper\r\n * @private\r\n */\r\n private _element: HTMLHeadingElement;\r\n\r\n \r\n\r\n constructor({ data, config, api, readOnly }: BlockToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n /**\r\n * Tool's settings passed from Editor\r\n *\r\n * @type {HeaderConfig}\r\n * @private\r\n */\r\n this._settings={placeholder:\"H5\"};\r\n\r\n /**\r\n * Block's data\r\n *\r\n * @type {HeaderData}\r\n * @private\r\n */\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * Main Block wrapper\r\n *\r\n * @type {HTMLElement}\r\n * @private\r\n */\r\n this._element = this.getTag();\r\n }\r\n /**\r\n * Styles\r\n */\r\n private get _CSS() {\r\n return {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-header',\r\n };\r\n }\r\n\r\n /**\r\n * Check if data is valid\r\n * \r\n * @param {any} data - data to check\r\n * @returns {data is HeaderData}\r\n * @private\r\n */\r\n isHeaderData(data: any): data is HeaderData {\r\n return (data as HeaderData).text !== undefined;\r\n }\r\n\r\n /**\r\n * Normalize input data\r\n *\r\n * @param {HeaderData} data - saved data to process\r\n *\r\n * @returns {HeaderData}\r\n * @private\r\n */\r\n normalizeData(data: HeaderData | {}): HeaderData {\r\n const newData: HeaderData = { text: '', level: this.defaultLevel.number };\r\n\r\n if (this.isHeaderData(data)) {\r\n newData.text = data.text || '';\r\n \r\n if (data.level !== undefined && !isNaN(parseInt(data.level.toString()))) {\r\n newData.level = parseInt(data.level.toString());\r\n }\r\n }\r\n\r\n return newData;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLHeadingElement}\r\n * @public\r\n */\r\n render(): HTMLHeadingElement {\r\n return this._element;\r\n }\r\n\r\n\r\n /**\r\n * Callback for Block's settings buttons\r\n *\r\n * @param {number} level - level to set\r\n */\r\n setLevel(level: number): void {\r\n this.data = {\r\n level: level,\r\n text: this.data.text,\r\n };\r\n }\r\n\r\n /**\r\n * Method that specified how to merge two Text blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * @param {HeaderData} data - saved data to merger with current block\r\n * @public\r\n */\r\n merge(data: HeaderData): void {\r\n this._element.insertAdjacentHTML('beforeend', data.text)\r\n }\r\n\r\n /**\r\n * Validate Text block data:\r\n * - check for emptiness\r\n *\r\n * @param {HeaderData} blockData — data received after saving\r\n * @returns {boolean} false if saved data is not correct, otherwise true\r\n * @public\r\n */\r\n validate(blockData: HeaderData): boolean {\r\n return blockData.text.trim() !== '';\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n *\r\n * @param {HTMLHeadingElement} toolsContent - Text tools rendered view\r\n * @returns {HeaderData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLHeadingElement): HeaderData {\r\n return {\r\n text: toolsContent.innerHTML,\r\n level: this.defaultLevel.number,\r\n };\r\n }\r\n\r\n /**\r\n * Allow Header to be converted to/from other blocks\r\n */\r\n static get conversionConfig() {\r\n return {\r\n export: 'text', // use 'text' property for other blocks\r\n import: 'text', // fill 'text' property from other block's export string\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer Rules\r\n */\r\n static get sanitize() {\r\n return {\r\n level: false,\r\n text: {},\r\n };\r\n }\r\n\r\n /**\r\n * Returns true to notify core that read-only is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get current Tools`s data\r\n *\r\n * @returns {HeaderData} Current data\r\n * @private\r\n */\r\n get data(): HeaderData {\r\n this._data.text = this._element.innerHTML;\r\n this._data.level = this.defaultLevel.number;\r\n \r\n return this._data;\r\n }\r\n\r\n /**\r\n * Store data in plugin:\r\n * - at the this._data property\r\n * - at the HTML\r\n *\r\n * @param {HeaderData} data — data to set\r\n * @private\r\n */\r\n set data(data: HeaderData) {\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * If level is set and block in DOM\r\n * then replace it to a new block\r\n */\r\n if (data.level !== undefined && this._element.parentNode) {\r\n /**\r\n * Create a new tag\r\n *\r\n * @type {HTMLHeadingElement}\r\n */\r\n const newHeader = this.getTag();\r\n\r\n /**\r\n * Save Block's content\r\n */\r\n newHeader.innerHTML = this._element.innerHTML;\r\n\r\n /**\r\n * Replace blocks\r\n */\r\n this._element.parentNode.replaceChild(newHeader, this._element);\r\n\r\n /**\r\n * Save new block to private variable\r\n *\r\n * @type {HTMLHeadingElement}\r\n * @private\r\n */\r\n this._element = newHeader;\r\n }\r\n\r\n /**\r\n * If data.text was passed then update block's content\r\n */\r\n if (data.text !== undefined) {\r\n this._element.innerHTML = this._data.text || '';\r\n }\r\n }\r\n\r\n /**\r\n * Get tag for target level\r\n * By default returns second-leveled header\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n getTag(): HTMLHeadingElement {\r\n const tag = this.createHeadingElement();\r\n this.setElementContent(tag);\r\n this.addStylesToElement(tag);\r\n this.setEditability(tag);\r\n this.addPlaceholder(tag);\r\n return tag;\r\n }\r\n\r\n /**\r\n * 创建标题元素\r\n * @returns {HTMLHeadingElement} 创建的HTML标题元素\r\n * @private\r\n */\r\n private createHeadingElement(): HTMLHeadingElement {\r\n return document.createElement(this.defaultLevel.tag) as HTMLHeadingElement;\r\n }\r\n\r\n /**\r\n * 设置元素内容\r\n * @param {HTMLHeadingElement} element - 要设置内容的HTML标题元素\r\n * @private\r\n */\r\n private setElementContent(element: HTMLHeadingElement): void {\r\n element.innerHTML = this._data.text || '';\r\n }\r\n\r\n /**\r\n * 为元素添加样式类\r\n * @param {HTMLHeadingElement} element - 要添加样式的HTML标题元素\r\n * @private\r\n */\r\n private addStylesToElement(element: HTMLHeadingElement): void {\r\n element.classList.add(this._CSS.wrapper);\r\n }\r\n\r\n /**\r\n * 设置元素可编辑属性\r\n * @param {HTMLHeadingElement} element - 要设置编辑属性的HTML标题元素\r\n * @private\r\n */\r\n private setEditability(element: HTMLHeadingElement): void {\r\n element.contentEditable = this.readOnly ? 'false' : 'true';\r\n }\r\n\r\n /**\r\n * 为元素添加占位符文本\r\n * @param {HTMLHeadingElement} element - 要添加占位符的HTML标题元素\r\n * @private\r\n */\r\n private addPlaceholder(element: HTMLHeadingElement): void {\r\n element.dataset.placeholder = this.api.i18n.t(this._settings.placeholder || '');\r\n }\r\n\r\n\r\n\r\n /**\r\n * Return default level\r\n *\r\n * @returns {level}\r\n */\r\n get defaultLevel(): Level {\r\n return {\r\n number: 5,\r\n tag: 'H5',\r\n svg: IconH5,\r\n };\r\n }\r\n\r\n\r\n\r\n\r\n /**\r\n * Handle H1-H6 tags on paste to substitute it with header Tool\r\n *\r\n * @param {PasteEvent} event - event with pasted content\r\n */\r\n onPaste(event: PasteEvent): void {\r\n const detail = event.detail;\r\n\r\n if ('data' in detail) {\r\n const content = detail.data as HTMLElement;\r\n this.data = {\r\n level: 5,\r\n text: content.innerHTML,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Used by Editor.js paste handling API.\r\n * Provides configuration to handle H1-H6 tags.\r\n *\r\n * @returns {{handler: (function(HTMLElement): {text: string}), tags: string[]}}\r\n */\r\n static get pasteConfig() {\r\n return {\r\n tags: ['H5'],\r\n };\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @returns {{icon: string, title: string}}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: IconH5,\r\n title: 'H5',\r\n };\r\n }\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\n\r\n\r\nimport { API, PasteEvent } from '@ebl-vue/editorjs';\r\nimport type { HeaderData, HeaderConfig, Level } from './types';\r\nimport type { BlockTool, BlockToolConstructorOptions } from '@ebl-vue/editorjs';\r\n\r\n\r\nimport { IconH6 } from '../../icons';\r\n\r\n/**\r\n * Header block for the Editor.js.\r\n *\r\n * @author CodeX (team@ifmo.su)\r\n * @copyright CodeX 2018\r\n * @license MIT\r\n * @version 2.0.0\r\n */\r\nexport default class H6 implements BlockTool {\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {{data: HeaderData, config: HeaderConfig, api: object}}\r\n * data — previously saved data\r\n * config - user config for Tool\r\n * api - Editor.js API\r\n * readOnly - read only mode flag\r\n */\r\n /**\r\n * Editor.js API\r\n * @private\r\n */\r\n private api: API;\r\n /**\r\n * Read-only mode flag\r\n * @private\r\n */\r\n private readOnly: boolean;\r\n /**\r\n * Tool's settings passed from Editor\r\n * @private\r\n */\r\n private _settings: HeaderConfig;\r\n /**\r\n * Block's data\r\n * @private\r\n */\r\n private _data: HeaderData;\r\n /**\r\n * Main Block wrapper\r\n * @private\r\n */\r\n private _element: HTMLHeadingElement;\r\n\r\n \r\n\r\n constructor({ data, config, api, readOnly }: BlockToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n /**\r\n * Tool's settings passed from Editor\r\n *\r\n * @type {HeaderConfig}\r\n * @private\r\n */\r\n this._settings={placeholder:\"H6\"};\r\n\r\n /**\r\n * Block's data\r\n *\r\n * @type {HeaderData}\r\n * @private\r\n */\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * Main Block wrapper\r\n *\r\n * @type {HTMLElement}\r\n * @private\r\n */\r\n this._element = this.getTag();\r\n }\r\n /**\r\n * Styles\r\n */\r\n private get _CSS() {\r\n return {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-header',\r\n };\r\n }\r\n\r\n /**\r\n * Check if data is valid\r\n * \r\n * @param {any} data - data to check\r\n * @returns {data is HeaderData}\r\n * @private\r\n */\r\n isHeaderData(data: any): data is HeaderData {\r\n return (data as HeaderData).text !== undefined;\r\n }\r\n\r\n /**\r\n * Normalize input data\r\n *\r\n * @param {HeaderData} data - saved data to process\r\n *\r\n * @returns {HeaderData}\r\n * @private\r\n */\r\n normalizeData(data: HeaderData | {}): HeaderData {\r\n const newData: HeaderData = { text: '', level: this.defaultLevel.number };\r\n\r\n if (this.isHeaderData(data)) {\r\n newData.text = data.text || '';\r\n \r\n if (data.level !== undefined && !isNaN(parseInt(data.level.toString()))) {\r\n newData.level = parseInt(data.level.toString());\r\n }\r\n }\r\n\r\n return newData;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLHeadingElement}\r\n * @public\r\n */\r\n render(): HTMLHeadingElement {\r\n return this._element;\r\n }\r\n\r\n\r\n /**\r\n * Callback for Block's settings buttons\r\n *\r\n * @param {number} level - level to set\r\n */\r\n setLevel(level: number): void {\r\n this.data = {\r\n level: level,\r\n text: this.data.text,\r\n };\r\n }\r\n\r\n /**\r\n * Method that specified how to merge two Text blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * @param {HeaderData} data - saved data to merger with current block\r\n * @public\r\n */\r\n merge(data: HeaderData): void {\r\n this._element.insertAdjacentHTML('beforeend', data.text)\r\n }\r\n\r\n /**\r\n * Validate Text block data:\r\n * - check for emptiness\r\n *\r\n * @param {HeaderData} blockData — data received after saving\r\n * @returns {boolean} false if saved data is not correct, otherwise true\r\n * @public\r\n */\r\n validate(blockData: HeaderData): boolean {\r\n return blockData.text.trim() !== '';\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n *\r\n * @param {HTMLHeadingElement} toolsContent - Text tools rendered view\r\n * @returns {HeaderData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLHeadingElement): HeaderData {\r\n return {\r\n text: toolsContent.innerHTML,\r\n level: this.defaultLevel.number,\r\n };\r\n }\r\n\r\n /**\r\n * Allow Header to be converted to/from other blocks\r\n */\r\n static get conversionConfig() {\r\n return {\r\n export: 'text', // use 'text' property for other blocks\r\n import: 'text', // fill 'text' property from other block's export string\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer Rules\r\n */\r\n static get sanitize() {\r\n return {\r\n level: false,\r\n text: {},\r\n };\r\n }\r\n\r\n /**\r\n * Returns true to notify core that read-only is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get current Tools`s data\r\n *\r\n * @returns {HeaderData} Current data\r\n * @private\r\n */\r\n get data(): HeaderData {\r\n this._data.text = this._element.innerHTML;\r\n this._data.level = this.defaultLevel.number;\r\n \r\n return this._data;\r\n }\r\n\r\n /**\r\n * Store data in plugin:\r\n * - at the this._data property\r\n * - at the HTML\r\n *\r\n * @param {HeaderData} data — data to set\r\n * @private\r\n */\r\n set data(data: HeaderData) {\r\n this._data = this.normalizeData(data);\r\n\r\n /**\r\n * If level is set and block in DOM\r\n * then replace it to a new block\r\n */\r\n if (data.level !== undefined && this._element.parentNode) {\r\n /**\r\n * Create a new tag\r\n *\r\n * @type {HTMLHeadingElement}\r\n */\r\n const newHeader = this.getTag();\r\n\r\n /**\r\n * Save Block's content\r\n */\r\n newHeader.innerHTML = this._element.innerHTML;\r\n\r\n /**\r\n * Replace blocks\r\n */\r\n this._element.parentNode.replaceChild(newHeader, this._element);\r\n\r\n /**\r\n * Save new block to private variable\r\n *\r\n * @type {HTMLHeadingElement}\r\n * @private\r\n */\r\n this._element = newHeader;\r\n }\r\n\r\n /**\r\n * If data.text was passed then update block's content\r\n */\r\n if (data.text !== undefined) {\r\n this._element.innerHTML = this._data.text || '';\r\n }\r\n }\r\n\r\n /**\r\n * Get tag for target level\r\n * By default returns second-leveled header\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n getTag(): HTMLHeadingElement {\r\n const tag = this.createHeadingElement();\r\n this.setElementContent(tag);\r\n this.addStylesToElement(tag);\r\n this.setEditability(tag);\r\n this.addPlaceholder(tag);\r\n return tag;\r\n }\r\n\r\n /**\r\n * 创建标题元素\r\n * @returns {HTMLHeadingElement} 创建的HTML标题元素\r\n * @private\r\n */\r\n private createHeadingElement(): HTMLHeadingElement {\r\n return document.createElement(this.defaultLevel.tag) as HTMLHeadingElement;\r\n }\r\n\r\n /**\r\n * 设置元素内容\r\n * @param {HTMLHeadingElement} element - 要设置内容的HTML标题元素\r\n * @private\r\n */\r\n private setElementContent(element: HTMLHeadingElement): void {\r\n element.innerHTML = this._data.text || '';\r\n }\r\n\r\n /**\r\n * 为元素添加样式类\r\n * @param {HTMLHeadingElement} element - 要添加样式的HTML标题元素\r\n * @private\r\n */\r\n private addStylesToElement(element: HTMLHeadingElement): void {\r\n element.classList.add(this._CSS.wrapper);\r\n }\r\n\r\n /**\r\n * 设置元素可编辑属性\r\n * @param {HTMLHeadingElement} element - 要设置编辑属性的HTML标题元素\r\n * @private\r\n */\r\n private setEditability(element: HTMLHeadingElement): void {\r\n element.contentEditable = this.readOnly ? 'false' : 'true';\r\n }\r\n\r\n /**\r\n * 为元素添加占位符文本\r\n * @param {HTMLHeadingElement} element - 要添加占位符的HTML标题元素\r\n * @private\r\n */\r\n private addPlaceholder(element: HTMLHeadingElement): void {\r\n element.dataset.placeholder = this.api.i18n.t(this._settings.placeholder || '');\r\n }\r\n\r\n\r\n\r\n /**\r\n * Return default level\r\n *\r\n * @returns {level}\r\n */\r\n get defaultLevel(): Level {\r\n return {\r\n number: 6,\r\n tag: 'H6',\r\n svg: IconH6,\r\n };\r\n }\r\n\r\n\r\n\r\n\r\n /**\r\n * Handle H1-H6 tags on paste to substitute it with header Tool\r\n *\r\n * @param {PasteEvent} event - event with pasted content\r\n */\r\n onPaste(event: PasteEvent): void {\r\n const detail = event.detail;\r\n\r\n if ('data' in detail) {\r\n const content = detail.data as HTMLElement;\r\n this.data = {\r\n level: 6,\r\n text: content.innerHTML,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Used by Editor.js paste handling API.\r\n * Provides configuration to handle H1-H6 tags.\r\n *\r\n * @returns {{handler: (function(HTMLElement): {text: string}), tags: string[]}}\r\n */\r\n static get pasteConfig() {\r\n return {\r\n tags: ['H6'],\r\n };\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @returns {{icon: string, title: string}}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: IconH6,\r\n title: 'H6',\r\n \r\n };\r\n }\r\n}\r\n","import \"./index.css\"\r\nimport type { API, BlockTune, ToolConfig } from \"@ebl-vue/editorjs/types\";\r\nimport { IconAlignLeft,IconAlignCenter,IconAlignRight } from \"../../icons\";\r\n\r\ninterface ConstructorArgs {\r\n data: AlignmentData;\r\n config?: ToolConfig;\r\n api: API;\r\n block?: any;\r\n}\r\nexport interface AlignmentData {\r\n text?: string;\r\n alignment: string\r\n}\r\n\r\nexport default class BlockAlignment implements BlockTune{\r\n private settings: ToolConfig;\r\n private block: any;\r\n private api: API;\r\n private data: AlignmentData;\r\n private alignmentSettings: any[];\r\n private _CSS: any;\r\n private wrapper: HTMLElement | undefined;\r\n\r\n\r\n static get DEFAULT_ALIGNMENT() {\r\n return 'left';\r\n }\r\n\r\n static get isTune() {\r\n return true;\r\n }\r\n\r\n getAlignment() {\r\n if (!!this.settings?.blocks && this.settings.blocks.hasOwnProperty(this.block.name)) {\r\n return this.settings.blocks[this.block.name]\r\n }\r\n if (!!this.settings?.default) {\r\n return this.settings.default\r\n }\r\n return BlockAlignment.DEFAULT_ALIGNMENT\r\n }\r\n\r\n constructor({ api, data, config, block }: ConstructorArgs) {\r\n this.api = api;\r\n this.block = block;\r\n\r\n this.settings = config;\r\n this.data = data || { alignment: this.getAlignment() }\r\n this.alignmentSettings = [\r\n {\r\n name: 'left',\r\n icon: IconAlignLeft\r\n },\r\n {\r\n name: 'center',\r\n icon: IconAlignCenter\r\n },\r\n {\r\n name: 'right',\r\n icon: IconAlignRight\r\n }\r\n ];\r\n this._CSS = {\r\n alignment: {\r\n left: 'ce-tune-alignment--left',\r\n center: 'ce-tune-alignment--center',\r\n right: 'ce-tune-alignment--right',\r\n }\r\n }\r\n }\r\n\r\n\r\n wrap(blockContent: HTMLElement) {\r\n this.wrapper = document.createElement(\"div\");\r\n this.wrapper!.classList.toggle(this._CSS.alignment[this.data.alignment])\r\n this.wrapper!.append(blockContent)\r\n return this.wrapper\r\n }\r\n\r\n\r\n render() {\r\n const wrapper = document.createElement(\"div\");\r\n this.alignmentSettings.map(align => {\r\n const button = document.createElement('button');\r\n button.classList.add(this.api.styles.settingsButton);\r\n button.innerHTML = align.icon;\r\n button.type = 'button';\r\n\r\n button.classList.toggle(this.api.styles.settingsButtonActive, align.name === this.data.alignment);\r\n const buttonTooltip = this.api.i18n.t(align.name + \" align\");\r\n this.api.tooltip.onHover(button, buttonTooltip, {\r\n placement: 'top',\r\n });\r\n wrapper.appendChild(button);\r\n return button\r\n }).forEach((element, index, elements) => {\r\n element.addEventListener('click', () => {\r\n this.data = {\r\n alignment: this.alignmentSettings[index].name\r\n }\r\n elements.forEach((el, i) => {\r\n const { name } = this.alignmentSettings[i];\r\n el.classList.toggle(this.api.styles.settingsButtonActive, name === this.data.alignment);\r\n this.wrapper!.classList.toggle(this._CSS.alignment[name], name === this.data.alignment)\r\n });\r\n });\r\n });\r\n return wrapper;\r\n }\r\n\r\n\r\n save() {\r\n return this.data;\r\n }\r\n}\r\n\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\n\r\nimport makeFragment from './utils/makeFragment';\r\nimport type { BlockToolConstructorOptions } from '@ebl-vue/editorjs';\r\nimport {IconText} from \"../../icons\";\r\nexport type ToolConstructorOptions = BlockToolConstructorOptions<ParagraphData>;\r\n\r\n\r\nimport type {\r\n API,\r\n ConversionConfig,\r\n HTMLPasteEvent,\r\n PasteConfig,\r\n SanitizerConfig,\r\n ToolConfig,\r\n ToolboxConfig,\r\n} from '@ebl-vue/editorjs';\r\n\r\n/**\r\n * Base Paragraph Block for the Editor.js.\r\n * Represents a regular text block\r\n *\r\n * @author CodeX (team@codex.so)\r\n * @copyright CodeX 2018\r\n * @license The MIT License (MIT)\r\n */\r\n\r\n/**\r\n * @typedef {object} ParagraphConfig\r\n * @property {string} placeholder - placeholder for the empty paragraph\r\n * @property {boolean} preserveBlank - Whether or not to keep blank paragraphs when saving editor data\r\n */\r\nexport interface ParagraphConfig extends ToolConfig {\r\n /**\r\n * Placeholder for the empty paragraph\r\n */\r\n placeholder?: string;\r\n\r\n /**\r\n * Whether or not to keep blank paragraphs when saving editor data\r\n */\r\n preserveBlank?: boolean;\r\n}\r\n\r\n/**\r\n * @typedef {object} ParagraphData\r\n * @description Tool's input and output data format\r\n * @property {string} text — Paragraph's content. Can include HTML tags: <a><b><i>\r\n */\r\nexport interface ParagraphData {\r\n /**\r\n * Paragraph's content\r\n */\r\n text: string;\r\n}\r\n\r\n/**\r\n * @typedef {object} ParagraphParams\r\n * @description Constructor params for the Paragraph tool, use to pass initial data and settings\r\n * @property {ParagraphData} data - Preload data for the paragraph.\r\n * @property {ParagraphConfig} config - The configuration for the paragraph.\r\n * @property {API} api - The Editor.js API.\r\n * @property {boolean} readOnly - Is paragraph is read-only.\r\n */\r\n// interface ParagraphParams {\r\n// /**\r\n// * Initial data for the paragraph\r\n// */\r\n// data: ParagraphData;\r\n// /**\r\n// * Paragraph tool configuration\r\n// */\r\n// config: ParagraphConfig;\r\n// /**\r\n// * Editor.js API\r\n// */\r\n// api: API;\r\n// /**\r\n// * Is paragraph read-only.\r\n// */\r\n// readOnly: boolean;\r\n// }\r\n\r\n/**\r\n * @typedef {object} ParagraphCSS\r\n * @description CSS classes names\r\n * @property {string} block - Editor.js CSS Class for block\r\n * @property {string} wrapper - Paragraph CSS Class\r\n */\r\ninterface ParagraphCSS {\r\n /**\r\n * Editor.js CSS Class for block\r\n */\r\n block: string;\r\n /**\r\n * Paragraph CSS Class\r\n */\r\n wrapper: string;\r\n}\r\n\r\nexport default class Paragraph {\r\n /**\r\n * Default placeholder for Paragraph Tool\r\n *\r\n * @returns {string}\r\n * @class\r\n */\r\n static get DEFAULT_PLACEHOLDER() {\r\n return '';\r\n }\r\n\r\n /**\r\n * The Editor.js API\r\n */\r\n api: API;\r\n\r\n /**\r\n * Is Paragraph Tool read-only\r\n */\r\n readOnly: boolean;\r\n\r\n /**\r\n * Paragraph Tool's CSS classes\r\n */\r\n private _CSS: ParagraphCSS;\r\n\r\n /**\r\n * Placeholder for Paragraph Tool\r\n */\r\n private _placeholder: string;\r\n\r\n /**\r\n * Paragraph's data\r\n */\r\n private _data: ParagraphData;\r\n\r\n /**\r\n * Paragraph's main Element\r\n */\r\n private _element: HTMLDivElement | null;\r\n\r\n /**\r\n * Whether or not to keep blank paragraphs when saving editor data\r\n */\r\n private _preserveBlank: boolean;\r\n\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {object} params - constructor params\r\n * @param {ParagraphData} params.data - previously saved data\r\n * @param {ParagraphConfig} params.config - user config for Tool\r\n * @param {object} params.api - editor.js api\r\n * @param {boolean} readOnly - read only mode flag\r\n */\r\n constructor({ data, config, api, readOnly }: ToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n this._CSS = {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-paragraph',\r\n };\r\n\r\n if (!this.readOnly) {\r\n this.onKeyUp = this.onKeyUp.bind(this);\r\n }\r\n\r\n /**\r\n * Placeholder for paragraph if it is first Block\r\n *\r\n * @type {string}\r\n */\r\n this._placeholder = config.placeholder\r\n ? config.placeholder\r\n : Paragraph.DEFAULT_PLACEHOLDER;\r\n this._data = data ?? {};\r\n this._element = null;\r\n this._preserveBlank = config.preserveBlank ?? false;\r\n }\r\n\r\n /**\r\n * Check if text content is empty and set empty string to inner html.\r\n * We need this because some browsers (e.g. Safari) insert <br> into empty contenteditanle elements\r\n *\r\n * @param {KeyboardEvent} e - key up event\r\n */\r\n onKeyUp(e: KeyboardEvent): void {\r\n if (e.code !== 'Backspace' && e.code !== 'Delete') {\r\n return;\r\n }\r\n\r\n if (!this._element) {\r\n return;\r\n }\r\n\r\n const { textContent } = this._element;\r\n\r\n if (textContent === '') {\r\n this._element.innerHTML = '';\r\n }\r\n }\r\n\r\n /**\r\n * Create Tool's view\r\n *\r\n * @returns {HTMLDivElement}\r\n * @private\r\n */\r\n drawView(): HTMLDivElement {\r\n const div = document.createElement('DIV');\r\n\r\n div.classList.add(this._CSS.wrapper, this._CSS.block);\r\n div.contentEditable = 'false';\r\n div.dataset.placeholderActive = this.api.i18n.t(this._placeholder);\r\n\r\n if (this._data.text) {\r\n div.innerHTML = this._data.text;\r\n }\r\n\r\n if (!this.readOnly) {\r\n div.contentEditable = 'true';\r\n div.addEventListener('keyup', this.onKeyUp);\r\n }\r\n\r\n /**\r\n * bypass property 'align' required in html div element\r\n */\r\n return div as HTMLDivElement;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLDivElement}\r\n */\r\n render(): HTMLDivElement {\r\n this._element = this.drawView();\r\n\r\n return this._element;\r\n }\r\n\r\n\r\n\r\n /**\r\n * Method that specified how to merge two Text blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * @param {ParagraphData} data\r\n * @public\r\n */\r\n merge(data: ParagraphData): void {\r\n if (!this._element) {\r\n return;\r\n }\r\n\r\n this._data.text += data.text;\r\n\r\n /**\r\n * We use appendChild instead of innerHTML to keep the links of the existing nodes\r\n * (for example, shadow caret)\r\n */\r\n const fragment = makeFragment(data.text);\r\n\r\n this._element.appendChild(fragment);\r\n\r\n this._element.normalize();\r\n }\r\n\r\n /**\r\n * Validate Paragraph block data:\r\n * - check for emptiness\r\n *\r\n * @param {ParagraphData} savedData — data received after saving\r\n * @returns {boolean} false if saved data is not correct, otherwise true\r\n * @public\r\n */\r\n validate(savedData: ParagraphData): boolean {\r\n if (savedData.text.trim() === '' && !this._preserveBlank) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n *\r\n * @param {HTMLDivElement} toolsContent - Paragraph tools rendered view\r\n * @returns {ParagraphData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLDivElement): ParagraphData {\r\n return {\r\n text: toolsContent.innerHTML,\r\n };\r\n }\r\n\r\n /**\r\n * On paste callback fired from Editor.\r\n *\r\n * @param {HTMLPasteEvent} event - event with pasted data\r\n */\r\n onPaste(event: HTMLPasteEvent): void {\r\n const data = {\r\n text: event.detail.data.innerHTML,\r\n };\r\n\r\n this._data = data;\r\n\r\n /**\r\n * We use requestAnimationFrame for performance purposes\r\n */\r\n window.requestAnimationFrame(() => {\r\n if (!this._element) {\r\n return;\r\n }\r\n this._element.innerHTML = this._data.text || '';\r\n });\r\n }\r\n\r\n /**\r\n * Enable Conversion Toolbar. Paragraph can be converted to/from other tools\r\n * @returns {ConversionConfig}\r\n */\r\n static get conversionConfig(): ConversionConfig {\r\n return {\r\n export: 'text', // to convert Paragraph to other block, use 'text' property of saved data\r\n import: 'text', // to covert other block's exported string to Paragraph, fill 'text' property of tool data\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer rules\r\n * @returns {SanitizerConfig} - Edtior.js sanitizer config\r\n */\r\n static get sanitize(): SanitizerConfig {\r\n return {\r\n text: {\r\n br: true,\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Returns true to notify the core that read-only mode is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Used by Editor paste handling API.\r\n * Provides configuration to handle P tags.\r\n *\r\n * @returns {PasteConfig} - Paragraph Paste Setting\r\n */\r\n static get pasteConfig(): PasteConfig {\r\n return {\r\n tags: ['P'],\r\n };\r\n }\r\n\r\n /**\r\n * Icon and title for displaying at the Toolbox\r\n *\r\n * @returns {ToolboxConfig} - Paragraph Toolbox Setting\r\n */\r\n static get toolbox(): ToolboxConfig {\r\n return {\r\n icon: IconText,\r\n title: 'Text',\r\n\r\n };\r\n }\r\n}\r\n","/**\r\n * Create a DocumentFragment and fill it with HTML from a string\r\n *\r\n * @param {string} htmlString - A string of valid HTML\r\n * @returns {DocumentFragment}\r\n */\r\nexport default function makeFragment(htmlString: string): DocumentFragment {\r\n const tempDiv = document.createElement('div');\r\n\r\n tempDiv.innerHTML = htmlString.trim();\r\n\r\n const fragment = document.createDocumentFragment();\r\n\r\n fragment.append(...Array.from(tempDiv.childNodes));\r\n\r\n return fragment;\r\n}\r\n","//https://github.com/yudaapratama/editorjs-shiki\r\nimport './index.css';\r\nimport type { API, BlockTool, BlockToolConstructorOptions, BlockToolData, PasteConfig, PasteEvent, SanitizerConfig, ToolboxConfig } from '@ebl-vue/editorjs';\r\nimport { codeToHtml, bundledLanguagesInfo as languages } from 'shiki'\r\nimport { getLineStartPosition } from './utils/string';\r\nimport { IconCode ,IconCopy} from \"../../icons\";\r\n\r\n/**\r\n * CodeTool for Editor.js\r\n * @version 1.0.0\r\n * @license MIT\r\n */\r\n\r\n/**\r\n * Data structure for CodeTool's data\r\n */\r\nexport type CodeData = BlockToolData<{\r\n /**\r\n * The code content input by the user\r\n */\r\n code: string;\r\n lang: string;\r\n theme: string;\r\n}>;\r\n\r\n/**\r\n * Configuration options for the CodeTool provided by the user\r\n */\r\nexport interface CodeConfig {\r\n /**\r\n * Placeholder text to display in the input field when it's empty\r\n */\r\n placeholder: string;\r\n}\r\n\r\n/**\r\n * Defines the CSS class names used by CodeTool for styling its elements\r\n */\r\ninterface CodeToolCSS {\r\n /** Block Styling from Editor.js API */\r\n baseClass: string;\r\n /** Input Styling from Editor.js API */\r\n input: string;\r\n /** Wrapper styling */\r\n wrapper: string;\r\n /** Textarea styling */\r\n textarea: string;\r\n /** Span styling */\r\n span: string;\r\n /** Selector Language styling */\r\n selectorLanguage: string;\r\n /** Selector Theme styling */\r\n selectorTheme: string;\r\n}\r\n\r\n/**\r\n * Holds references to the DOM elements used by CodeTool\r\n */\r\ninterface CodeToolNodes {\r\n /** Main container or Wrapper for CodeTool */\r\n holder: HTMLDivElement | null;\r\n /** Textarea where user inputs their code */\r\n textarea: HTMLTextAreaElement | null;\r\n}\r\n\r\n/**\r\n * Options passed to the constructor of a block tool\r\n */\r\nexport type CodeToolConstructorOptions = BlockToolConstructorOptions<CodeData>;\r\n\r\n/**\r\n * Code Tool for the Editor.js allows to include code examples in your articles.\r\n */\r\nexport default class CodeTool implements BlockTool {\r\n /**\r\n * API provided by Editor.js for interacting with the editor's core functionality\r\n */\r\n private api: API;\r\n /**\r\n * Indicates whether the editor is in read-only mode, preventing modifications\r\n */\r\n private readOnly: boolean;\r\n /**\r\n * Placeholder text displayed when there is no code content\r\n */\r\n private placeholder: string;\r\n /**\r\n * Collection of CSS class names used by CodeTool for styling its elements\r\n */\r\n private CSS: CodeToolCSS;\r\n /**\r\n * DOM nodes related to the CodeTool, including containers and other elements\r\n */\r\n private nodes: CodeToolNodes;\r\n /**\r\n * Stores the current data (code and other related properties) for the CodeTool\r\n */\r\n private _data!: CodeData;\r\n /**\r\n * Default language for the CodeTool\r\n */\r\n private _selectorLanguage: string = '';\r\n /**\r\n * Default theme for the CodeTool\r\n */\r\n private _selectorTheme: string = '';\r\n /**\r\n * Notify core that read-only mode is supported\r\n * @returns true if read-only mode is supported\r\n */\r\n public static get isReadOnlySupported(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Allows pressing Enter key to create line breaks inside the CodeTool textarea\r\n * This enables multi-line input within the code editor.\r\n * @returns true if line breaks are allowed in the textarea\r\n */\r\n public static get enableLineBreaks(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n * @param options - tool constricting options\r\n * @param options.data — previously saved plugin code\r\n * @param options.config - user config for Tool\r\n * @param options.api - Editor.js API\r\n * @param options.readOnly - read only mode flag\r\n */\r\n constructor({ data, config, api, readOnly }: CodeToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n this.placeholder = this.api.i18n.t(config.placeholder as string || CodeTool.DEFAULT_PLACEHOLDER);\r\n\r\n this._selectorLanguage = data.lang || config.lang || CodeTool.DEFAULT_LANGUAGE\r\n this._selectorTheme = data.theme || config.theme || CodeTool.DEFAULT_THEME\r\n\r\n this.CSS = {\r\n baseClass: this.api.styles.block,\r\n input: this.api.styles.input,\r\n wrapper: 'ce-editorjs-x-shiki',\r\n textarea: 'ce-editorjs-x-shiki__textarea',\r\n span: 'ce-editorjs-x-shiki__span',\r\n selectorLanguage: 'ce-editorjs-x-shiki__selector-language',\r\n selectorTheme: 'ce-editorjs-x-shiki__selector-theme',\r\n };\r\n\r\n this.nodes = {\r\n holder: null,\r\n textarea: null,\r\n };\r\n\r\n this.data = {\r\n code: data.code ?? '',\r\n lang: this._selectorLanguage,\r\n theme: this._selectorTheme,\r\n };\r\n\r\n this.nodes.holder = this.drawView()\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n * @returns this.nodes.holder - Code's wrapper\r\n */\r\n public render(): HTMLDivElement {\r\n return this.nodes.holder!;\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n * @param codeWrapper - CodeTool's wrapper, containing textarea with code\r\n * @returns - saved plugin code\r\n */\r\n public save(codeWrapper: HTMLDivElement): CodeData {\r\n return {\r\n code: codeWrapper.querySelector('textarea')!.value,\r\n lang: this._selectorLanguage,\r\n theme: this._selectorTheme\r\n };\r\n }\r\n\r\n /**\r\n * onPaste callback fired from Editor`s core\r\n * @param event - event with pasted content\r\n */\r\n public onPaste(event: PasteEvent): void {\r\n const detail = event.detail;\r\n\r\n if ('data' in detail) {\r\n const content = detail.data as string;\r\n\r\n this.data = {\r\n code: content || '',\r\n lang: this._selectorLanguage,\r\n theme: this._selectorTheme\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Returns Tool`s data from private property\r\n * @returns\r\n */\r\n public get data(): CodeData {\r\n return this._data;\r\n }\r\n\r\n /**\r\n * Set Tool`s data to private property and update view\r\n * @param data - saved tool data\r\n */\r\n public set data(data: CodeData) {\r\n this._data = data;\r\n\r\n if (this.nodes.textarea) {\r\n this.nodes.textarea.value = data.code;\r\n }\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings.\r\n * Provides the icon and title to display in the toolbox for the CodeTool.\r\n * @returns An object containing:\r\n * - icon: SVG representation of the Tool's icon\r\n * - title: Title to show in the toolbox\r\n */\r\n public static get toolbox(): ToolboxConfig {\r\n return {\r\n icon: IconCode,\r\n title: 'Code',\r\n };\r\n }\r\n\r\n /**\r\n * Default placeholder for CodeTool's textarea\r\n * @returns\r\n */\r\n public static get DEFAULT_PLACEHOLDER(): string {\r\n return 'Enter your code';\r\n }\r\n\r\n /**\r\n * Default language for CodeTool's textarea\r\n * @returns\r\n */\r\n public static get DEFAULT_LANGUAGE(): string {\r\n return 'javascript';\r\n }\r\n\r\n /**\r\n * Default theme for CodeTool's textarea\r\n * @returns\r\n */\r\n public static get DEFAULT_THEME(): string {\r\n return 'vitesse-dark';\r\n }\r\n\r\n /**\r\n * Used by Editor.js paste handling API.\r\n * Provides configuration to handle CODE tag.\r\n * @returns\r\n */\r\n public static get pasteConfig(): PasteConfig {\r\n return {\r\n tags: ['pre'],\r\n };\r\n }\r\n\r\n /**\r\n * Automatic sanitize config\r\n * @returns\r\n */\r\n public static get sanitize(): SanitizerConfig {\r\n return {\r\n code: true, // Allow HTML tags\r\n };\r\n }\r\n\r\n /**\r\n * Handles Tab key pressing (adds/removes indentations)\r\n * @param event - keydown\r\n */\r\n private tabHandler(event: KeyboardEvent): void {\r\n /**\r\n * Prevent editor.js tab handler\r\n */\r\n event.stopPropagation();\r\n\r\n /**\r\n * Prevent native tab behaviour\r\n */\r\n event.preventDefault();\r\n\r\n const textarea = event.target as HTMLTextAreaElement;\r\n const isShiftPressed = event.shiftKey;\r\n const caretPosition = textarea.selectionStart;\r\n const value = textarea.value;\r\n const indentation = ' ';\r\n\r\n let newCaretPosition;\r\n\r\n /**\r\n * For Tab pressing, just add an indentation to the caret position\r\n */\r\n if (!isShiftPressed) {\r\n newCaretPosition = caretPosition + indentation.length;\r\n\r\n textarea.value = value.substring(0, caretPosition) + indentation + value.substring(caretPosition);\r\n } else {\r\n /**\r\n * For Shift+Tab pressing, remove an indentation from the start of line\r\n */\r\n const currentLineStart = getLineStartPosition(value, caretPosition);\r\n const firstLineChars = value.substr(currentLineStart, indentation.length);\r\n\r\n if (firstLineChars !== indentation) {\r\n return;\r\n }\r\n\r\n /**\r\n * Trim the first two chars from the start of line\r\n */\r\n textarea.value = value.substring(0, currentLineStart) + value.substring(currentLineStart + indentation.length);\r\n newCaretPosition = caretPosition - indentation.length;\r\n }\r\n\r\n /**\r\n * Restore the caret\r\n */\r\n textarea.setSelectionRange(newCaretPosition, newCaretPosition);\r\n }\r\n\r\n /**\r\n * Create Tool's view\r\n * @returns\r\n */\r\n private drawView(): HTMLDivElement {\r\n const wrapper = document.createElement('div');\r\n const wrapperHolder = document.createElement('div');\r\n const wrapperSelectorHolder = document.createElement('div');\r\n const wrapperLang = document.createElement('div');\r\n const wrapperCopy = document.createElement('div');\r\n const wrapperCopyTip = document.createElement('div');\r\n \r\n\r\n const selectorLanguage = document.createElement('select');\r\n const selectorTheme = document.createElement('select');\r\n const span = document.createElement('span');\r\n const textarea = document.createElement('textarea');\r\n\r\n wrapper.classList.add(this.CSS.baseClass, this.CSS.wrapper);\r\n wrapperHolder.classList.add('ce-editorjs-x-shiki__code');\r\n wrapperSelectorHolder.classList.add('ce-editorjs-x-shiki__selector');\r\n wrapperLang.classList.add('ce-editorjs-x-shiki__lang');\r\n wrapperCopy.classList.add('ce-editorjs-x-shiki__copy');\r\n wrapperCopyTip.classList.add('ce-editorjs-x-shiki__copy_tip');\r\n\r\n selectorLanguage.classList.add(this.CSS.selectorLanguage);\r\n //selectorTheme.classList.add(this.CSS.selectorTheme);\r\n textarea.classList.add(this.CSS.textarea, this.CSS.input);\r\n\r\n wrapperLang.innerHTML = this.data.lang\r\n wrapperCopy.innerHTML = IconCopy;\r\n wrapperCopyTip.innerText=this.api.i18n.t('Copied');\r\n\r\n \r\n\r\n languages.forEach((lang) => {\r\n const option = document.createElement('option');\r\n option.value = lang.id;\r\n option.text = lang.name;\r\n selectorLanguage.appendChild(option);\r\n });\r\n selectorLanguage.value = this.data.lang\r\n\r\n // themes.forEach((theme) => {\r\n // const option = document.createElement('option');\r\n // option.value = theme.id;\r\n // option.text = theme.displayName;\r\n // selectorTheme.appendChild(option);\r\n // });\r\n // selectorTheme.value = this.data.theme\r\n\r\n textarea.value = this.data.code;\r\n textarea.placeholder = this.placeholder;\r\n textarea.spellcheck = false;\r\n textarea.autocomplete = \"off\"\r\n textarea.autocapitalize = \"off\"\r\n\r\n if (this.readOnly) {\r\n textarea.disabled = true;\r\n }\r\n\r\n wrapperHolder.appendChild(span);\r\n wrapperHolder.appendChild(textarea);\r\n \r\n if(!this.readOnly) {\r\n wrapperSelectorHolder.appendChild(selectorLanguage);\r\n //wrapperSelectorHolder.appendChild(selectorTheme);\r\n \r\n } else {\r\n wrapperSelectorHolder.appendChild(wrapperLang);\r\n \r\n }\r\n wrapperCopy.appendChild(wrapperCopyTip);\r\n\r\n wrapperSelectorHolder.appendChild(wrapperCopy);\r\n wrapper.appendChild(wrapperSelectorHolder);\r\n \r\n wrapper.appendChild(wrapperHolder);\r\n //wrapper.appendChild(wrapperLang);\r\n\r\n this.runShiki().then(({ html, preStyle }) => {\r\n\r\n span.innerHTML = html\r\n wrapper?.setAttribute('style', preStyle)\r\n selectorLanguage.setAttribute('style', preStyle)\r\n selectorTheme.setAttribute('style', preStyle)\r\n })\r\n\r\n selectorLanguage.addEventListener('change', (event: Event) => {\r\n const lang = (event.target as HTMLSelectElement).value\r\n this._selectorLanguage = lang\r\n this.runShiki().then(({ html, preStyle }) => {\r\n span.innerHTML = html\r\n wrapperLang.innerHTML = lang\r\n })\r\n })\r\n\r\n selectorTheme.addEventListener('change', (event: Event) => {\r\n const theme = (event.target as HTMLSelectElement).value\r\n this._selectorTheme = theme\r\n this.runShiki().then(({ html, preStyle }) => {\r\n span.innerHTML = html\r\n wrapper?.setAttribute('style', preStyle)\r\n selectorLanguage.setAttribute('style', preStyle)\r\n selectorTheme.setAttribute('style', preStyle)\r\n })\r\n })\r\n\r\n textarea.addEventListener('input', () => {\r\n this.data.code = textarea.value\r\n this.runShiki().then(({ html, preStyle }) => {\r\n span.innerHTML = html\r\n wrapper?.setAttribute('style', preStyle)\r\n selectorLanguage.setAttribute('style', preStyle)\r\n selectorTheme.setAttribute('style', preStyle)\r\n })\r\n })\r\n\r\n /**\r\n * Enable keydown handlers\r\n */\r\n textarea.addEventListener('keydown', (event) => {\r\n switch (event.code) {\r\n case 'Tab':\r\n this.tabHandler(event);\r\n this.data.code = textarea.value\r\n this.runShiki().then(({ html, preStyle }) => {\r\n span.innerHTML = html\r\n })\r\n break;\r\n }\r\n });\r\n wrapperCopy.addEventListener('click', (event: MouseEvent) => {\r\n this.copyCode(this.data.code,event);\r\n });\r\n\r\n this.nodes.textarea = textarea;\r\n\r\n return wrapper;\r\n }\r\n\r\n private async runShiki(): Promise<{ html: string, preStyle: string }> {\r\n let preStyle = ''\r\n\r\n const html = await codeToHtml(this.data.code, {\r\n lang: this._selectorLanguage,\r\n theme: this._selectorTheme,\r\n transformers: [\r\n {\r\n preprocess(code) {\r\n // if (code.endsWith('\\n'))\r\n return `${code}\\n`\r\n },\r\n pre(node) {\r\n this.addClassToHast(node, 'ce-editorjs-x-shiki__span')\r\n preStyle = node.properties?.style as string || ''\r\n },\r\n }\r\n ]\r\n })\r\n\r\n return {\r\n html,\r\n preStyle\r\n }\r\n\r\n }\r\n\r\n private copyCode(code: string, event: MouseEvent) {\r\n if (this.data.code) {\r\n navigator.clipboard.writeText(code)\r\n .then(() => { \r\n if (event.target) {\r\n const parentEle = (event.target as HTMLElement).parentElement;\r\n if (parentEle) {\r\n const tooltip = parentEle.lastChild as HTMLElement; \r\n if (tooltip) {\r\n tooltip.classList.add('visible');\r\n setTimeout(() => {\r\n tooltip.classList.remove('visible');\r\n\r\n }, 2000);\r\n }\r\n }\r\n }\r\n\r\n \r\n })\r\n .catch((err) => {\r\n console.error(err);\r\n alert(\"Unable to copy\");\r\n });\r\n }\r\n }\r\n}\r\n","/**\r\n * Return the position of line starting from passed point\r\n *\r\n * ┌───────────────┐\r\n * │1234\\n │\r\n * │2eda | dadd\\n │ <-- returns 5\r\n * └───────────────┘\r\n * @param string - string to process\r\n * @param position - search starting position\r\n * @returns\r\n */\r\nexport function getLineStartPosition(string: string, position: number): number {\r\n const charLength = 1;\r\n let char = '';\r\n\r\n /**\r\n * Iterate through all the chars before the position till the\r\n * - end of line (\\n)\r\n * - or start of string (position === 0)\r\n */\r\n while (char !== '\\n' && position > 0) {\r\n position = position - charLength;\r\n char = string.substr(position, charLength);\r\n }\r\n\r\n /**\r\n * Do not count the linebreak symbol because it is related to the previous line\r\n */\r\n if (char === '\\n') {\r\n position += 1;\r\n }\r\n\r\n return position;\r\n}\r\n","import \"./index.css\";\r\n\r\n\r\nimport { make } from \"@editorjs/dom\";\r\nimport type { API, BlockAPI, BlockTool } from \"@ebl-vue/editorjs\";\r\nimport { IconQuote } from \"../../icons\";\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Data structure for the Quote block.\r\n */\r\nexport interface QuoteData {\r\n text: string;\r\n}\r\n\r\n/**\r\n * Parameters for the Quote constructor.\r\n */\r\ninterface QuoteParams {\r\n data: QuoteData;\r\n api: API;\r\n readOnly: boolean;\r\n block: BlockAPI;\r\n}\r\n\r\n/**\r\n * CSS class names used in the Quote block.\r\n */\r\ninterface QuoteCSS {\r\n baseClass: string;\r\n wrapper: string;\r\n input: string;\r\n text: string;\r\n}\r\n\r\n\r\n\r\n/**\r\n * Quote class representing a customizable quote block for Editor.js.\r\n */\r\nexport default class Quote implements BlockTool {\r\n api: API;\r\n readOnly: boolean;\r\n\r\n\r\n private _data: QuoteData;\r\n private _CSS: QuoteCSS;\r\n private _quoteElement!: HTMLElement;\r\n\r\n /**\r\n * Creates an instance of the Quote block.\r\n * @param params - The parameters for the Quote block.\r\n */\r\n constructor({ data, api, readOnly }: QuoteParams) {\r\n\r\n\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n\r\n this._data = {\r\n text: data.text || \"\"\r\n };\r\n\r\n this._CSS = {\r\n baseClass: this.api.styles.block,\r\n wrapper: \"cdx-quote\",\r\n text: \"cdx-quote__text\",\r\n input: this.api.styles.input,\r\n };\r\n\r\n }\r\n\r\n static get isReadOnlySupported(): boolean {\r\n return true;\r\n }\r\n\r\n static get toolbox() {\r\n return {\r\n icon: IconQuote,\r\n title: \"Quote\",\r\n };\r\n }\r\n\r\n static get contentless(): boolean {\r\n return true;\r\n }\r\n\r\n static get enableLineBreaks(): boolean {\r\n return true;\r\n }\r\n\r\n\r\n\r\n static get conversionConfig() {\r\n return {\r\n import: \"text\",\r\n\r\n export: function (quoteData: QuoteData): string {\r\n return quoteData.text;\r\n },\r\n };\r\n }\r\n\r\n\r\n get CSS(): QuoteCSS {\r\n return {\r\n baseClass: this.api.styles.block,\r\n wrapper: \"cdx-quote\",\r\n text: \"cdx-quote__text\",\r\n input: this.api.styles.input,\r\n };\r\n }\r\n\r\n\r\n\r\n render(): HTMLElement {\r\n const container = make(\"div\", [this._CSS.baseClass, this._CSS.wrapper]);\r\n this._quoteElement = make(\r\n \"blockquote\",\r\n [this._CSS.input, this._CSS.text, \"cdx-block-quote\"],\r\n {\r\n contentEditable: !this.readOnly,\r\n innerHTML: this._data.text,\r\n }\r\n );\r\n\r\n this._quoteElement.addEventListener(\"keydown\", (event: KeyboardEvent) =>\r\n this.handleKeydown(event)\r\n );\r\n\r\n container.appendChild(this._quoteElement);\r\n return container;\r\n }\r\n\r\n\r\n get currentItem(): HTMLElement {\r\n let currentNode = window.getSelection()!.anchorNode;\r\n\r\n if (currentNode!.nodeType !== Node.ELEMENT_NODE) {\r\n currentNode = currentNode!.parentNode;\r\n }\r\n\r\n return (currentNode as Element).closest(`.${this.CSS.text}`) as HTMLElement;\r\n }\r\n\r\n\r\n handleKeydown(event: KeyboardEvent) {\r\n const currentItem = this._quoteElement;\r\n\r\n if (event.key === \"Enter\") {\r\n if (!event.shiftKey) {\r\n event.preventDefault();\r\n this.getOutOfQuote();\r\n }\r\n }\r\n\r\n if (\r\n event.key === \"Backspace\" &&\r\n currentItem.textContent?.trim().length === 0\r\n ) {\r\n event.preventDefault();\r\n\r\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\r\n this.api.blocks.delete(currentBlockIndex);\r\n this.api.blocks.insert(\"paragraph\", { text: \"\" });\r\n this.api.caret.setToBlock(currentBlockIndex);\r\n\r\n return;\r\n }\r\n }\r\n\r\n\r\n getOutOfQuote() {\r\n this.api.blocks.insert();\r\n this.api.caret.setToBlock(this.api.blocks.getCurrentBlockIndex());\r\n }\r\n\r\n\r\n\r\n\r\n save(quoteElement: HTMLDivElement): QuoteData {\r\n const text = quoteElement.querySelector(`.${this._CSS.text}`);\r\n\r\n return Object.assign(this._data, {\r\n text: text?.innerHTML ?? \"\",\r\n });\r\n }\r\n\r\n static get sanitize() {\r\n return {\r\n text: {\r\n br: true,\r\n },\r\n };\r\n }\r\n\r\n\r\n\r\n\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\nimport {API, BlockTool, BlockToolConstructorOptions, BlockToolData, ToolboxConfig, PasteConfig, PasteEvent} from \"@ebl-vue/editorjs\";\r\n\r\nimport {IconDelimiter} from '../../icons';\r\n\r\n\r\n\r\n\r\nexport default class Delimiter implements BlockTool {\r\n\r\n static get isReadOnlySupported(): boolean {\r\n return true;\r\n }\r\n\r\n\r\n static get contentless(): boolean {\r\n return true;\r\n }\r\n\r\n private api: API\r\n\r\n private _CSS: {\r\n block: string\r\n wrapper: string\r\n }\r\n\r\n\r\n\r\n private _element: HTMLDivElement\r\n private data: any;\r\n\r\n\r\n constructor({data, config, api}: BlockToolConstructorOptions) {\r\n this.api = api;\r\n\r\n this._CSS = {\r\n block: this.api.styles.block,\r\n wrapper: 'ce-delimiter'\r\n };\r\n\r\n this._element = this.drawView();\r\n this.data = data;\r\n\r\n }\r\n\r\n /**\r\n * Create Tool's view\r\n * @return {HTMLDivElement}\r\n * @private\r\n */\r\n drawView(): HTMLDivElement {\r\n let wrapper = document.createElement('div');\r\n let lineWrapper = document.createElement('div');\r\n let lineDiv = document.createElement('div');\r\n \r\n wrapper.classList.add(this._CSS.wrapper, this._CSS.block);\r\n lineWrapper.classList.add('ce-delimiter__line__wrapper');\r\n lineDiv.classList.add('ce-delimiter__line');\r\n\r\n lineWrapper.appendChild(lineDiv);\r\n wrapper.appendChild(lineWrapper);\r\n\r\n return wrapper;\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n * @returns {HTMLDivElement}\r\n * @public\r\n */\r\n render(): HTMLDivElement {\r\n console.log(this.data);\r\n return this._element;\r\n }\r\n\r\n /**\r\n * Extract Tool's data from the view\r\n * @param {HTMLDivElement} toolsContent - Paragraph tools rendered view\r\n * @returns {DelimiterData} - saved data\r\n * @public\r\n */\r\n save(toolsContent: HTMLElement): BlockToolData {\r\n return {};\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @return {{icon: string, title: string}}\r\n */\r\n static get toolbox(): ToolboxConfig {\r\n return {\r\n icon: IconDelimiter,\r\n title: 'Delimiter'\r\n };\r\n }\r\n\r\n /**\r\n * Delimiter onPaste configuration\r\n *\r\n * @public\r\n */\r\n static get pasteConfig(): PasteConfig {\r\n return { tags: ['HR'] };\r\n }\r\n\r\n /**\r\n * On paste callback that is fired from Editor\r\n *\r\n * @param {PasteEvent} event - event with pasted data\r\n */\r\n onPaste(event: PasteEvent): void {\r\n this.data = {};\r\n }\r\n}\r\n\r\n","/**\r\n * Default css prefix for list\r\n */\r\nexport const CssPrefix = 'cdx-list';\r\n","import { CssPrefix } from '../styles/CssPrefix';\r\n/**\r\n * CSS classes for the List Tool\r\n */\r\nexport const DefaultListCssClasses = {\r\n wrapper: CssPrefix,\r\n item: `${CssPrefix}__item`,\r\n itemContent: `${CssPrefix}__item-content`,\r\n itemChildren: `${CssPrefix}__item-children`,\r\n};\r\n\r\n/**\r\n * Interface that represents default list css classes\r\n */\r\nexport interface ListCssClasses {\r\n /**\r\n * CSS class of the whole list wrapper\r\n */\r\n wrapper: string;\r\n\r\n /**\r\n * CSS class of the list item\r\n */\r\n item: string;\r\n\r\n /**\r\n * CSS class of the list item content element\r\n */\r\n itemContent: string;\r\n\r\n /**\r\n * CSS class of the children item wrapper\r\n */\r\n itemChildren: string;\r\n}\r\n\r\n/**\r\n * Interface that represents all list renderer classes\r\n */\r\nexport interface ListRendererInterface<ItemMeta> {\r\n /**\r\n * Renders wrapper for list\r\n * @param isRoot - boolean variable that represents level of the wrappre (root or childList)\r\n * @returns - created html ul element\r\n */\r\n renderWrapper: (isRoot: boolean) => HTMLElement;\r\n\r\n /**\r\n * Redners list item element\r\n * @param content - content of the list item\r\n * @returns - created html list item element\r\n */\r\n renderItem: (content: string, meta: ItemMeta) => HTMLElement;\r\n\r\n /**\r\n * Return the item content\r\n * @param {Element} item - item wrapper (<li>)\r\n * @returns {string}\r\n */\r\n getItemContent: (item: Element) => string;\r\n\r\n /**\r\n * Return meta object of certain element\r\n * @param {Element} item - item of the list to get meta from\r\n * @returns {ItemMeta} Item meta object\r\n */\r\n getItemMeta: (item: Element) => ItemMeta;\r\n\r\n /**\r\n * Returns default item meta used on creation of the new item\r\n */\r\n composeDefaultMeta: () => ItemMeta;\r\n};\r\n","import type { OrderedListItemMeta } from '../types/ItemMeta';\r\nimport type { ListConfig } from '../types/ListParams';\r\nimport { isEmpty, make } from '@editorjs/dom';\r\nimport { DefaultListCssClasses } from './ListRenderer';\r\nimport type { ListCssClasses, ListRendererInterface } from './ListRenderer';\r\nimport { CssPrefix } from '../styles/CssPrefix';\r\n\r\n/**\r\n * Interface that represents all list used only in unordered list rendering\r\n */\r\ninterface OrderedListCssClasses extends ListCssClasses {\r\n /**\r\n * CSS class of the ordered list\r\n */\r\n orderedList: string;\r\n}\r\n\r\n/**\r\n * Class that is responsible for ordered list rendering\r\n */\r\nexport class OrderedListRenderer implements ListRendererInterface<OrderedListItemMeta> {\r\n /**\r\n * Tool's configuration\r\n */\r\n protected config?: ListConfig;\r\n\r\n /**\r\n * Is Editorjs List Tool read-only option\r\n */\r\n private readOnly: boolean;\r\n\r\n /**\r\n * Getter for all CSS classes used in unordered list rendering\r\n */\r\n private static get CSS(): OrderedListCssClasses {\r\n return {\r\n ...DefaultListCssClasses,\r\n orderedList: `${CssPrefix}-ordered`,\r\n };\r\n }\r\n\r\n /**\r\n * Assign passed readonly mode and config to relevant class properties\r\n * @param readonly - read-only mode flag\r\n * @param config - user config for Tool\r\n */\r\n constructor(readonly: boolean, config?: ListConfig) {\r\n this.config = config;\r\n this.readOnly = readonly;\r\n }\r\n\r\n /**\r\n * Renders ol wrapper for list\r\n * @param isRoot - boolean variable that represents level of the wrappre (root or childList)\r\n * @returns - created html ol element\r\n */\r\n public renderWrapper(isRoot: boolean): HTMLOListElement {\r\n let wrapperElement: HTMLOListElement;\r\n\r\n /**\r\n * Check if it's root level\r\n */\r\n if (isRoot === true) {\r\n wrapperElement = make('ol', [OrderedListRenderer.CSS.wrapper, OrderedListRenderer.CSS.orderedList]) as HTMLOListElement;\r\n } else {\r\n wrapperElement = make('ol', [OrderedListRenderer.CSS.orderedList, OrderedListRenderer.CSS.itemChildren]) as HTMLOListElement;\r\n }\r\n\r\n return wrapperElement;\r\n }\r\n\r\n /**\r\n * Redners list item element\r\n * @param content - content used in list item rendering\r\n * @param _meta - meta of the list item unused in rendering of the ordered list\r\n * @returns - created html list item element\r\n */\r\n public renderItem(content: string, _meta: OrderedListItemMeta): HTMLLIElement {\r\n const itemWrapper = make('li', OrderedListRenderer.CSS.item);\r\n const itemContent = make('div', OrderedListRenderer.CSS.itemContent, {\r\n innerHTML: content,\r\n contentEditable: (!this.readOnly).toString(),\r\n });\r\n\r\n itemWrapper.appendChild(itemContent);\r\n\r\n return itemWrapper as HTMLLIElement;\r\n }\r\n\r\n /**\r\n * Return the item content\r\n * @param item - item wrapper (<li>)\r\n * @returns - item content string\r\n */\r\n public getItemContent(item: Element): string {\r\n const contentNode = item.querySelector(`.${OrderedListRenderer.CSS.itemContent}`);\r\n\r\n if (!contentNode) {\r\n return '';\r\n }\r\n\r\n if (isEmpty(contentNode)) {\r\n return '';\r\n }\r\n\r\n return contentNode.innerHTML;\r\n }\r\n\r\n /**\r\n * Returns item meta, for ordered list\r\n * @returns item meta object\r\n */\r\n public getItemMeta(): OrderedListItemMeta {\r\n return {};\r\n }\r\n\r\n /**\r\n * Returns default item meta used on creation of the new item\r\n */\r\n public composeDefaultMeta(): OrderedListItemMeta {\r\n return {};\r\n }\r\n}\r\n","import type { UnorderedListItemMeta } from '../types/ItemMeta';\r\nimport type { ListConfig } from '../types/ListParams';\r\nimport { make, isEmpty } from '@editorjs/dom';\r\nimport { DefaultListCssClasses } from './ListRenderer';\r\nimport type { ListCssClasses, ListRendererInterface } from './ListRenderer';\r\nimport { CssPrefix } from '../styles/CssPrefix';\r\n\r\n/**\r\n * Interface that represents all list used only in unordered list rendering\r\n */\r\ninterface UnoderedListCssClasses extends ListCssClasses {\r\n /**\r\n * CSS class of the unordered list\r\n */\r\n unorderedList: string;\r\n}\r\n\r\n/**\r\n * Class that is responsible for unordered list rendering\r\n */\r\nexport class UnorderedListRenderer implements ListRendererInterface<UnorderedListItemMeta> {\r\n /**\r\n * Tool's configuration\r\n */\r\n protected config?: ListConfig;\r\n\r\n /**\r\n * Is Editorjs List Tool read-only option\r\n */\r\n private readOnly: boolean;\r\n\r\n /**\r\n * Getter for all CSS classes used in unordered list rendering\r\n */\r\n private static get CSS(): UnoderedListCssClasses {\r\n return {\r\n ...DefaultListCssClasses,\r\n unorderedList: `${CssPrefix}-unordered`,\r\n };\r\n }\r\n\r\n /**\r\n * Assign passed readonly mode and config to relevant class properties\r\n * @param readonly - read-only mode flag\r\n * @param config - user config for Tool\r\n */\r\n constructor(readonly: boolean, config?: ListConfig) {\r\n this.config = config;\r\n this.readOnly = readonly;\r\n }\r\n\r\n /**\r\n * Renders ol wrapper for list\r\n * @param isRoot - boolean variable that represents level of the wrappre (root or childList)\r\n * @returns - created html ul element\r\n */\r\n public renderWrapper(isRoot: boolean): HTMLUListElement {\r\n let wrapperElement: HTMLUListElement;\r\n\r\n /**\r\n * Check if it's root level\r\n */\r\n if (isRoot === true) {\r\n wrapperElement = make('ul', [UnorderedListRenderer.CSS.wrapper, UnorderedListRenderer.CSS.unorderedList]) as HTMLUListElement;\r\n } else {\r\n wrapperElement = make('ul', [UnorderedListRenderer.CSS.unorderedList, UnorderedListRenderer.CSS.itemChildren]) as HTMLUListElement;\r\n }\r\n\r\n return wrapperElement;\r\n }\r\n\r\n /**\r\n * Redners list item element\r\n * @param content - content used in list item rendering\r\n * @param _meta - meta of the list item unused in rendering of the unordered list\r\n * @returns - created html list item element\r\n */\r\n public renderItem(content: string, _meta: UnorderedListItemMeta): HTMLLIElement {\r\n const itemWrapper = make('li', UnorderedListRenderer.CSS.item);\r\n const itemContent = make('div', UnorderedListRenderer.CSS.itemContent, {\r\n innerHTML: content,\r\n contentEditable: (!this.readOnly).toString(),\r\n });\r\n\r\n itemWrapper.appendChild(itemContent);\r\n\r\n return itemWrapper as HTMLLIElement;\r\n }\r\n\r\n /**\r\n * Return the item content\r\n * @param item - item wrapper (<li>)\r\n * @returns - item content string\r\n */\r\n public getItemContent(item: Element): string {\r\n const contentNode = item.querySelector(`.${UnorderedListRenderer.CSS.itemContent}`);\r\n\r\n if (!contentNode) {\r\n return '';\r\n }\r\n\r\n if (isEmpty(contentNode)) {\r\n return '';\r\n }\r\n\r\n return contentNode.innerHTML;\r\n }\r\n\r\n /**\r\n * Returns item meta, for unordered list\r\n * @returns Item meta object\r\n */\r\n public getItemMeta(): UnorderedListItemMeta {\r\n return {};\r\n }\r\n\r\n /**\r\n * Returns default item meta used on creation of the new item\r\n */\r\n public composeDefaultMeta(): UnorderedListItemMeta {\r\n return {};\r\n }\r\n}\r\n","/**\r\n * Type guard to check if a node is an HTMLElement, then we can safely use it as an HTMLElement\r\n * @param node - Node to be checked, wherever it is an HTMLElement\r\n */\r\nexport function isHtmlElement(node: Node): node is HTMLElement {\r\n // node is an HTMLElement if it is an element node\r\n return node.nodeType === Node.ELEMENT_NODE;\r\n}\r\n","import type { ChecklistItemMeta } from '../types/ItemMeta';\r\nimport type { ListConfig } from '../types/ListParams';\r\nimport { isEmpty, make } from '@editorjs/dom';\r\nimport { DefaultListCssClasses } from './ListRenderer';\r\nimport type { ListCssClasses, ListRendererInterface } from './ListRenderer';\r\nimport { CssPrefix } from '../styles/CssPrefix';\r\nimport { IconCheck } from \"../../../icons\"; \r\n\r\n/**\r\n * Interface that represents all list used only in unordered list rendering\r\n */\r\ninterface ChecklistCssClasses extends ListCssClasses {\r\n /**\r\n * CSS class of the checklist\r\n */\r\n checklist: string;\r\n\r\n /**\r\n * CSS class of the checked checkbox\r\n */\r\n itemChecked: string;\r\n\r\n /**\r\n * CSS class for the special hover behavior of the checkboc\r\n */\r\n noHover: string;\r\n\r\n /**\r\n * CSS class of the checkbox\r\n */\r\n checkbox: string;\r\n\r\n /**\r\n * CSS class of the checkbox container\r\n */\r\n checkboxContainer: string;\r\n\r\n /**\r\n * CSS class for disabled checkbox check\r\n */\r\n checkboxCheckDisabled: string;\r\n}\r\n\r\n/**\r\n * Class that is responsible for checklist rendering\r\n */\r\nexport class CheckListRenderer implements ListRendererInterface<ChecklistItemMeta> {\r\n /**\r\n * Tool's configuration\r\n */\r\n protected config?: ListConfig;\r\n\r\n /**\r\n * Is Editorjs List Tool read-only option\r\n */\r\n private readOnly: boolean;\r\n\r\n /**\r\n * Getter for all CSS classes used in unordered list rendering\r\n */\r\n private static get CSS(): ChecklistCssClasses {\r\n return {\r\n ...DefaultListCssClasses,\r\n checklist: `${CssPrefix}-checklist`,\r\n itemChecked: `${CssPrefix}__checkbox--checked`,\r\n noHover: `${CssPrefix}__checkbox--no-hover`,\r\n checkbox: `${CssPrefix}__checkbox-check`,\r\n checkboxContainer: `${CssPrefix}__checkbox`,\r\n checkboxCheckDisabled: `${CssPrefix}__checkbox-check--disabled`,\r\n };\r\n }\r\n\r\n /**\r\n * Assign passed readonly mode and config to relevant class properties\r\n * @param readonly - read-only mode flag\r\n * @param config - user config for Tool\r\n */\r\n constructor(readonly: boolean, config?: ListConfig) {\r\n this.config = config;\r\n this.readOnly = readonly;\r\n }\r\n\r\n /**\r\n * Renders ul wrapper for list\r\n * @param isRoot - boolean variable that represents level of the wrappre (root or childList)\r\n * @returns - created html ul element\r\n */\r\n public renderWrapper(isRoot: boolean): HTMLUListElement {\r\n let wrapperElement: HTMLUListElement;\r\n\r\n /**\r\n * Check if it's root level\r\n */\r\n if (isRoot === true) {\r\n wrapperElement = make('ul', [CheckListRenderer.CSS.wrapper, CheckListRenderer.CSS.checklist]) as HTMLUListElement;\r\n\r\n /**\r\n * Delegate clicks from wrapper to items\r\n */\r\n wrapperElement.addEventListener('click', (event) => {\r\n const target = event.target as Element | null;\r\n\r\n if (target) {\r\n const checkbox = target.closest(`.${CheckListRenderer.CSS.checkboxContainer}`);\r\n\r\n if (checkbox && checkbox.contains(target)) {\r\n this.toggleCheckbox(checkbox);\r\n }\r\n }\r\n });\r\n } else {\r\n wrapperElement = make('ul', [CheckListRenderer.CSS.checklist, CheckListRenderer.CSS.itemChildren]) as HTMLUListElement;\r\n }\r\n\r\n return wrapperElement;\r\n }\r\n\r\n /**\r\n * Redners list item element\r\n * @param content - content used in list item rendering\r\n * @param meta - meta of the list item used in rendering of the checklist\r\n * @returns - created html list item element\r\n */\r\n public renderItem(content: string, meta: ChecklistItemMeta): HTMLLIElement {\r\n const itemWrapper = make('li', [CheckListRenderer.CSS.item, CheckListRenderer.CSS.item]);\r\n const itemContent = make('div', CheckListRenderer.CSS.itemContent, {\r\n innerHTML: content,\r\n contentEditable: (!this.readOnly).toString(),\r\n });\r\n\r\n const checkbox = make('span', CheckListRenderer.CSS.checkbox);\r\n const checkboxContainer = make('div', CheckListRenderer.CSS.checkboxContainer);\r\n\r\n if (meta.checked === true) {\r\n checkboxContainer.classList.add(CheckListRenderer.CSS.itemChecked);\r\n }\r\n\r\n // Disable checkbox interaction in read-only mode\r\n if (this.readOnly) {\r\n checkboxContainer.classList.add(CheckListRenderer.CSS.checkboxCheckDisabled);\r\n }\r\n\r\n checkbox.innerHTML = IconCheck;\r\n checkboxContainer.appendChild(checkbox);\r\n\r\n itemWrapper.appendChild(checkboxContainer);\r\n itemWrapper.appendChild(itemContent);\r\n\r\n return itemWrapper as HTMLLIElement;\r\n }\r\n\r\n /**\r\n * Return the item content\r\n * @param item - item wrapper (<li>)\r\n * @returns - item content string\r\n */\r\n public getItemContent(item: Element): string {\r\n const contentNode = item.querySelector(`.${CheckListRenderer.CSS.itemContent}`);\r\n\r\n if (!contentNode) {\r\n return '';\r\n }\r\n\r\n if (isEmpty(contentNode)) {\r\n return '';\r\n }\r\n\r\n return contentNode.innerHTML;\r\n }\r\n\r\n /**\r\n * Return meta object of certain element\r\n * @param item - will be returned meta information of this item\r\n * @returns Item meta object\r\n */\r\n public getItemMeta(item: Element): ChecklistItemMeta {\r\n const checkbox = item.querySelector(`.${CheckListRenderer.CSS.checkboxContainer}`);\r\n\r\n return {\r\n checked: checkbox ? checkbox.classList.contains(CheckListRenderer.CSS.itemChecked) : false,\r\n };\r\n }\r\n\r\n /**\r\n * Returns default item meta used on creation of the new item\r\n */\r\n public composeDefaultMeta(): ChecklistItemMeta {\r\n return { checked: false };\r\n }\r\n\r\n /**\r\n * Toggle checklist item state\r\n * @param checkbox - checkbox element to be toggled\r\n */\r\n private toggleCheckbox(checkbox: Element): void {\r\n checkbox.classList.toggle(CheckListRenderer.CSS.itemChecked);\r\n checkbox.classList.add(CheckListRenderer.CSS.noHover);\r\n checkbox.addEventListener('mouseleave', () => this.removeSpecialHoverBehavior(checkbox), { once: true });\r\n }\r\n\r\n /**\r\n * Removes class responsible for special hover behavior on an item\r\n * @param el - item wrapper\r\n */\r\n private removeSpecialHoverBehavior(el: Element): void {\r\n el.classList.remove(CheckListRenderer.CSS.noHover);\r\n }\r\n}\r\n","/**\r\n * Get all siblings before passed element, or after it\r\n * @param element - html element whose siblings would be returned\r\n * @param direction - wherever siblings would be returned, after element of before it\r\n */\r\nexport function getSiblings(element: HTMLElement, direction: 'after' | 'before' = 'after'): Element[] | null {\r\n const siblings: Element[] = [];\r\n\r\n let nextElementSibling: HTMLElement;\r\n\r\n /**\r\n * Method that is responsible for getting next element sibling responsible to the direction variable\r\n * @param el - current element\r\n * @returns HTML element of the sibling\r\n */\r\n function getNextElementSibling(el: HTMLElement): HTMLElement {\r\n /**\r\n * Get first sibling element respectfully to passed direction\r\n */\r\n switch (direction) {\r\n case 'after':\r\n return el.nextElementSibling as HTMLElement;\r\n\r\n case 'before':\r\n return el.previousElementSibling as HTMLElement;\r\n }\r\n }\r\n\r\n nextElementSibling = getNextElementSibling(element);\r\n\r\n /**\r\n * Iterate by all siblings elements\r\n */\r\n while (nextElementSibling !== null) {\r\n siblings.push(nextElementSibling);\r\n\r\n /**\r\n * Get next element sibling\r\n */\r\n nextElementSibling = getNextElementSibling(nextElementSibling);\r\n }\r\n\r\n /**\r\n * Check that formed siblings array is not empty\r\n * If it is emtpy, return null\r\n */\r\n if (siblings.length !== 0) {\r\n return siblings;\r\n }\r\n\r\n return null;\r\n}\r\n","import { DefaultListCssClasses } from '../ListRenderer';\r\nimport type { ItemChildWrapperElement, ItemElement } from '../types/Elements';\r\n\r\n/**\r\n * Get child items of the passed element\r\n * @param element - child items would be got from this element\r\n * @param firstLevelChildren - if method should return all level child items or only first level ones\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-duplicate-type-constituents\r\nexport function getChildItems(element: ItemElement | ItemChildWrapperElement, firstLevelChildren: boolean = true): ItemElement[] {\r\n let itemChildWrapper: HTMLElement = element;\r\n\r\n /**\r\n * If passed element is list item than get item's child wrapper\r\n */\r\n if (element.classList.contains(DefaultListCssClasses.item)) {\r\n itemChildWrapper = element.querySelector(`.${DefaultListCssClasses.itemChildren}`) as HTMLElement;\r\n }\r\n\r\n /**\r\n * Check if itemChildWrapper is not null\r\n */\r\n if (itemChildWrapper === null) {\r\n return [];\r\n }\r\n\r\n if (firstLevelChildren) {\r\n /**\r\n * Filter first level child items of the curret child item wrapper\r\n * In case that child could be not only list item\r\n */\r\n return Array.from(itemChildWrapper.querySelectorAll(`:scope > .${DefaultListCssClasses.item}`));\r\n } else {\r\n /**\r\n * Filter all levels child items of the current child item wrapper\r\n * In case that child could be not only list item\r\n */\r\n return Array.from(itemChildWrapper.querySelectorAll(`.${DefaultListCssClasses.item}`));\r\n }\r\n}\r\n","import type { ItemChildWrapperElement, ItemElement } from '../types/Elements';\r\nimport { DefaultListCssClasses } from '../ListRenderer';\r\n\r\n/**\r\n * Returns child wrapper element of the passed item\r\n * @param item - wrapper element would be got from this item\r\n */\r\nexport function getItemChildWrapper(item: ItemElement): ItemChildWrapperElement | null {\r\n return item.querySelector(`.${DefaultListCssClasses.itemChildren}`);\r\n}\r\n","import { DefaultListCssClasses } from '../ListRenderer';\r\nimport type { ItemChildWrapperElement, ItemElement } from '../types/Elements';\r\nimport { getChildItems } from './getChildItems';\r\nimport { getItemChildWrapper } from './getItemChildWrapper';\r\n\r\n/**\r\n * Method that will remove passed child wrapper if it has no child items\r\n * @param element - child wrapper or actual item, from where we get child wrapper\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-duplicate-type-constituents\r\nexport function removeChildWrapperIfEmpty(element: ItemChildWrapperElement | ItemElement): void {\r\n let itemChildWrapper: HTMLElement | null = element;\r\n\r\n /**\r\n * If passed element is list item than get item's child wrapper\r\n */\r\n if (element.classList.contains(DefaultListCssClasses.item)) {\r\n itemChildWrapper = getItemChildWrapper(element);\r\n }\r\n\r\n if (itemChildWrapper === null) {\r\n return;\r\n }\r\n\r\n /**\r\n * Check that there is at least one item\r\n */\r\n if (getChildItems(itemChildWrapper).length === 0) {\r\n itemChildWrapper.remove();\r\n }\r\n}\r\n","import type { ItemContentElement, ItemElement } from '../types/Elements';\r\nimport { DefaultListCssClasses } from '../ListRenderer';\r\n\r\n/**\r\n * Returns content element of the passed item\r\n * @param item - content element would be got from this item\r\n */\r\nexport function getItemContentElement(item: ItemElement): ItemContentElement | null {\r\n return item.querySelector(`.${DefaultListCssClasses.itemContent}`);\r\n}\r\n","import { focus } from '@editorjs/caret';\r\nimport type { ItemElement } from '../types/Elements';\r\nimport { getItemContentElement } from './getItemContentElement';\r\n\r\n/**\r\n * Sets focus to the item's content\r\n * @param item - item (<li>) to select\r\n * @param atStart - where to set focus: at the start or at the end\r\n */\r\nexport function focusItem(item: ItemElement, atStart: boolean = true): void {\r\n const itemContent = getItemContentElement(item);\r\n\r\n if (!itemContent) {\r\n return;\r\n }\r\n\r\n focus(itemContent, atStart);\r\n}\r\n","import { OrderedListRenderer } from '../ListRenderer/OrderedListRenderer';\r\nimport { UnorderedListRenderer } from '../ListRenderer/UnorderedListRenderer';\r\nimport type { ListConfig, ListData, ListDataStyle } from '../types/ListParams';\r\nimport type { ListItem } from '../types/ListParams';\r\nimport type { ItemElement, ItemChildWrapperElement } from '../types/Elements';\r\nimport { isHtmlElement } from '../utils/type-guards';\r\nimport { getContenteditableSlice, getCaretNodeAndOffset, isCaretAtStartOfInput } from '@editorjs/caret';\r\nimport { DefaultListCssClasses } from '../ListRenderer';\r\nimport type { PasteEvent } from '../types';\r\nimport type { API, BlockAPI, PasteConfig } from '@editorjs/editorjs';\r\nimport type { ListParams } from '..';\r\nimport type { ChecklistItemMeta, ItemMeta, OrderedListItemMeta, UnorderedListItemMeta } from '../types/ItemMeta';\r\nimport type { ListRenderer } from '../types/ListRenderer';\r\nimport { getSiblings } from '../utils/getSiblings';\r\nimport { getChildItems } from '../utils/getChildItems';\r\nimport { isLastItem } from '../utils/isLastItem';\r\nimport { itemHasSublist } from '../utils/itemHasSublist';\r\nimport { getItemChildWrapper } from '../utils/getItemChildWrapper';\r\nimport { removeChildWrapperIfEmpty } from '../utils/removeChildWrapperIfEmpty';\r\nimport { getItemContentElement } from '../utils/getItemContentElement';\r\nimport { focusItem } from '../utils/focusItem';\r\nimport type { OlCounterType } from '../types/OlCounterType';\r\n\r\n/**\r\n * Class that is responsible for list tabulation\r\n */\r\nexport default class ListTabulator<Renderer extends ListRenderer> {\r\n /**\r\n * The Editor.js API\r\n */\r\n private api: API;\r\n\r\n /**\r\n * Is Editorjs List Tool read-only option\r\n */\r\n private readOnly: boolean;\r\n\r\n /**\r\n * Tool's configuration\r\n */\r\n private config?: ListConfig;\r\n\r\n /**\r\n * Full content of the list\r\n */\r\n private data: ListData;\r\n\r\n /**\r\n * Editor block api\r\n */\r\n private block: BlockAPI;\r\n\r\n /**\r\n * Rendered list of items\r\n */\r\n private renderer: Renderer;\r\n\r\n /**\r\n * Wrapper of the whole list\r\n */\r\n private listWrapper: ItemChildWrapperElement | undefined;\r\n\r\n /**\r\n * Getter method to get current item\r\n * @returns current list item or null if caret position is not undefined\r\n */\r\n private get currentItem(): ItemElement | null {\r\n const selection = window.getSelection();\r\n\r\n if (!selection) {\r\n return null;\r\n }\r\n\r\n let currentNode = selection.anchorNode;\r\n\r\n if (!currentNode) {\r\n return null;\r\n }\r\n\r\n if (!isHtmlElement(currentNode)) {\r\n currentNode = currentNode.parentNode;\r\n }\r\n if (!currentNode) {\r\n return null;\r\n }\r\n if (!isHtmlElement(currentNode)) {\r\n return null;\r\n }\r\n\r\n return currentNode.closest(`.${DefaultListCssClasses.item}`);\r\n }\r\n\r\n /**\r\n * Method that returns nesting level of the current item, null if there is no selection\r\n */\r\n private get currentItemLevel(): number | null {\r\n const currentItem = this.currentItem;\r\n\r\n if (currentItem === null) {\r\n return null;\r\n }\r\n\r\n let parentNode = currentItem.parentNode;\r\n\r\n let levelCounter = 0;\r\n\r\n while (parentNode !== null && parentNode !== this.listWrapper) {\r\n if (isHtmlElement(parentNode) && parentNode.classList.contains(DefaultListCssClasses.item)) {\r\n levelCounter += 1;\r\n }\r\n\r\n parentNode = parentNode.parentNode;\r\n }\r\n\r\n /**\r\n * Level counter is number of the parent element, so it should be increased by one\r\n */\r\n return levelCounter + 1;\r\n }\r\n\r\n /**\r\n * Assign all passed params and renderer to relevant class properties\r\n * @param params - tool constructor options\r\n * @param params.data - previously saved data\r\n * @param params.config - user config for Tool\r\n * @param params.api - Editor.js API\r\n * @param params.readOnly - read-only mode flag\r\n * @param renderer - renderer instance initialized in tool class\r\n */\r\n constructor({ data, config, api, readOnly, block }: ListParams, renderer: Renderer) {\r\n this.config = config;\r\n this.data = data as ListData;\r\n this.readOnly = readOnly;\r\n this.api = api;\r\n this.block = block;\r\n\r\n this.renderer = renderer;\r\n }\r\n\r\n /**\r\n * Function that is responsible for rendering list with contents\r\n * @returns Filled with content wrapper element of the list\r\n */\r\n public render(): ItemChildWrapperElement {\r\n this.listWrapper = this.renderer.renderWrapper(true);\r\n\r\n // fill with data\r\n if (this.data.items.length) {\r\n this.appendItems(this.data.items, this.listWrapper);\r\n } else {\r\n this.appendItems(\r\n [\r\n {\r\n content: '',\r\n meta: {},\r\n items: [],\r\n },\r\n ],\r\n this.listWrapper\r\n );\r\n }\r\n\r\n if (!this.readOnly) {\r\n // detect keydown on the last item to escape List\r\n this.listWrapper.addEventListener(\r\n 'keydown',\r\n (event) => {\r\n switch (event.key) {\r\n case 'Enter':\r\n if (!event.shiftKey) {\r\n this.enterPressed(event);\r\n }\r\n break;\r\n case 'Backspace':\r\n this.backspace(event);\r\n break;\r\n case 'Tab':\r\n if (event.shiftKey) {\r\n this.shiftTab(event);\r\n } else {\r\n this.addTab(event);\r\n }\r\n break;\r\n }\r\n },\r\n false\r\n );\r\n }\r\n\r\n /**\r\n * Set start property value from initial data\r\n */\r\n if ('start' in this.data.meta && this.data.meta.start !== undefined) {\r\n this.changeStartWith(this.data.meta.start);\r\n }\r\n\r\n /**\r\n * Set counterType value from initial data\r\n */\r\n if ('counterType' in this.data.meta && this.data.meta.counterType !== undefined) {\r\n this.changeCounters(this.data.meta.counterType);\r\n }\r\n\r\n return this.listWrapper;\r\n }\r\n\r\n /**\r\n * Function that is responsible for list content saving\r\n * @param wrapper - optional argument wrapper\r\n * @returns whole list saved data if wrapper not passes, otherwise will return data of the passed wrapper\r\n */\r\n public save(wrapper?: ItemChildWrapperElement): ListData {\r\n const listWrapper = wrapper ?? this.listWrapper;\r\n\r\n /**\r\n * The method for recursive collecting of the child items\r\n * @param parent - where to find items\r\n */\r\n const getItems = (parent: ItemChildWrapperElement): ListItem[] => {\r\n const children = getChildItems(parent);\r\n\r\n return children.map((el) => {\r\n const subItemsWrapper = getItemChildWrapper(el);\r\n const content = this.renderer.getItemContent(el);\r\n const meta = this.renderer.getItemMeta(el);\r\n const subItems = subItemsWrapper ? getItems(subItemsWrapper) : [];\r\n\r\n return {\r\n content,\r\n meta,\r\n items: subItems,\r\n };\r\n });\r\n };\r\n\r\n const composedListItems = listWrapper ? getItems(listWrapper) : [];\r\n\r\n let dataToSave: ListData = {\r\n style: this.data.style,\r\n meta: {} as ItemMeta,\r\n items: composedListItems,\r\n };\r\n\r\n if (this.data.style === 'ordered') {\r\n dataToSave.meta = {\r\n start: (this.data.meta as OrderedListItemMeta).start,\r\n counterType: (this.data.meta as OrderedListItemMeta).counterType,\r\n };\r\n }\r\n\r\n return dataToSave;\r\n }\r\n\r\n /**\r\n * On paste sanitzation config. Allow only tags that are allowed in the Tool.\r\n * @returns - config that determines tags supposted by paste handler\r\n * @todo - refactor and move to list instance\r\n */\r\n public static get pasteConfig(): PasteConfig {\r\n return {\r\n tags: ['OL', 'UL', 'LI'],\r\n };\r\n }\r\n\r\n /**\r\n * Method that specified hot to merge two List blocks.\r\n * Called by Editor.js by backspace at the beginning of the Block\r\n *\r\n * Content of the first item of the next List would be merged with deepest item in current list\r\n * Other items of the next List would be appended to the current list without any changes in nesting levels\r\n * @param data - data of the second list to be merged with current\r\n */\r\n public merge(data: ListData): void {\r\n /**\r\n * Get list of all levels children of the previous item\r\n */\r\n const items = this.block.holder.querySelectorAll<ItemElement>(`.${DefaultListCssClasses.item}`);\r\n\r\n const deepestBlockItem = items[items.length - 1];\r\n const deepestBlockItemContentElement = getItemContentElement(deepestBlockItem);\r\n\r\n if (deepestBlockItem === null || deepestBlockItemContentElement === null) {\r\n return;\r\n }\r\n\r\n /**\r\n * Insert trailing html to the deepest block item content\r\n */\r\n deepestBlockItemContentElement.insertAdjacentHTML('beforeend', data.items[0].content);\r\n\r\n if (this.listWrapper === undefined) {\r\n return;\r\n }\r\n\r\n const firstLevelItems = getChildItems(this.listWrapper);\r\n\r\n if (firstLevelItems.length === 0) {\r\n return;\r\n }\r\n\r\n /**\r\n * Get last item of the first level of the list\r\n */\r\n const lastFirstLevelItem = firstLevelItems[firstLevelItems.length - 1];\r\n\r\n /**\r\n * Get child items wrapper of the last item\r\n */\r\n let lastFirstLevelItemChildWrapper = getItemChildWrapper(lastFirstLevelItem);\r\n\r\n /**\r\n * Get first item of the list to be merged with current one\r\n */\r\n const firstItem = data.items.shift();\r\n\r\n /**\r\n * Check that first item exists\r\n */\r\n if (firstItem === undefined) {\r\n return;\r\n }\r\n\r\n /**\r\n * Append child items of the first element\r\n */\r\n if (firstItem.items.length !== 0) {\r\n /**\r\n * Render child wrapper of the last item if it does not exist\r\n */\r\n if (lastFirstLevelItemChildWrapper === null) {\r\n lastFirstLevelItemChildWrapper = this.renderer.renderWrapper(false);\r\n }\r\n\r\n this.appendItems(firstItem.items, lastFirstLevelItemChildWrapper);\r\n }\r\n\r\n if (data.items.length > 0) {\r\n this.appendItems(data.items, this.listWrapper);\r\n }\r\n }\r\n\r\n /**\r\n * On paste callback that is fired from Editor.\r\n * @param event - event with pasted data\r\n * @todo - refactor and move to list instance\r\n */\r\n public onPaste(event: PasteEvent): void {\r\n const list = event.detail.data;\r\n\r\n this.data = this.pasteHandler(list);\r\n\r\n // render new list\r\n const oldView = this.listWrapper;\r\n\r\n if (oldView && oldView.parentNode) {\r\n oldView.parentNode.replaceChild(this.render(), oldView);\r\n }\r\n }\r\n\r\n /**\r\n * Handle UL, OL and LI tags paste and returns List data\r\n * @param element - html element that contains whole list\r\n * @todo - refactor and move to list instance\r\n */\r\n public pasteHandler(element: PasteEvent['detail']['data']): ListData {\r\n const { tagName: tag } = element;\r\n let style: ListDataStyle = 'unordered';\r\n let tagToSearch: string;\r\n\r\n // set list style and tag to search.\r\n switch (tag) {\r\n case 'OL':\r\n style = 'ordered';\r\n tagToSearch = 'ol';\r\n break;\r\n case 'UL':\r\n case 'LI':\r\n style = 'unordered';\r\n tagToSearch = 'ul';\r\n }\r\n\r\n const data: ListData = {\r\n style,\r\n meta: {} as ItemMeta,\r\n items: [],\r\n };\r\n\r\n /**\r\n * Set default ordered list atributes if style is ordered\r\n */\r\n if (style === 'ordered') {\r\n (this.data.meta as OrderedListItemMeta).counterType = 'numeric';\r\n (this.data.meta as OrderedListItemMeta).start = 1;\r\n }\r\n\r\n // get pasted items from the html.\r\n const getPastedItems = (parent: Element): ListItem[] => {\r\n // get first level li elements.\r\n const children = Array.from(parent.querySelectorAll(`:scope > li`));\r\n\r\n return children.map((child) => {\r\n // get subitems if they exist.\r\n const subItemsWrapper = child.querySelector(`:scope > ${tagToSearch}`);\r\n // get subitems.\r\n const subItems = subItemsWrapper ? getPastedItems(subItemsWrapper) : [];\r\n // get text content of the li element.\r\n const content = child.innerHTML ?? '';\r\n\r\n return {\r\n content,\r\n meta: {},\r\n items: subItems,\r\n };\r\n });\r\n };\r\n\r\n // get pasted items.\r\n data.items = getPastedItems(element);\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * Changes ordered list start property value\r\n * @param index - new value of the start property\r\n */\r\n public changeStartWith(index: number): void {\r\n this.listWrapper!.style.setProperty('counter-reset', `item ${index - 1}`);\r\n\r\n (this.data.meta as OrderedListItemMeta).start = index;\r\n }\r\n\r\n /**\r\n * Changes ordered list counterType property value\r\n * @param counterType - new value of the counterType value\r\n */\r\n public changeCounters(counterType: OlCounterType): void {\r\n this.listWrapper!.style.setProperty('--list-counter-type', counterType);\r\n\r\n (this.data.meta as OrderedListItemMeta).counterType = counterType;\r\n }\r\n\r\n /**\r\n * Handles Enter keypress\r\n * @param event - keydown\r\n */\r\n private enterPressed(event: KeyboardEvent): void {\r\n const currentItem = this.currentItem;\r\n\r\n /**\r\n * Prevent editor.js behaviour\r\n */\r\n event.stopPropagation();\r\n\r\n /**\r\n * Prevent browser behaviour\r\n */\r\n event.preventDefault();\r\n\r\n /**\r\n * Prevent duplicated event in Chinese, Japanese and Korean languages\r\n */\r\n if (event.isComposing) {\r\n return;\r\n }\r\n if (currentItem === null) {\r\n return;\r\n }\r\n\r\n const isEmpty = this.renderer?.getItemContent(currentItem).trim().length === 0;\r\n const isFirstLevelItem = currentItem.parentNode === this.listWrapper;\r\n const isFirstItem = currentItem.previousElementSibling === null;\r\n\r\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\r\n\r\n /**\r\n * On Enter in the last empty item, get out of list\r\n */\r\n if (isFirstLevelItem && isEmpty) {\r\n if (isLastItem(currentItem) && !itemHasSublist(currentItem)) {\r\n /**\r\n * If current item is first and last item of the list, then empty list should be deleted after deletion of the item\r\n */\r\n if (isFirstItem) {\r\n this.convertItemToDefaultBlock(currentBlockIndex, true);\r\n } else {\r\n /**\r\n * If there are other items in the list, just remove current item and get out of the list\r\n */\r\n this.convertItemToDefaultBlock();\r\n }\r\n\r\n return;\r\n } else {\r\n /**\r\n * If enter is pressed in the сenter of the list item we should split it\r\n */\r\n this.splitList(currentItem);\r\n\r\n return;\r\n }\r\n } else if (isEmpty) {\r\n /**\r\n * If currnet item is empty and is in the middle of the list\r\n * And if current item is not on the first level\r\n * Then unshift current item\r\n */\r\n this.unshiftItem(currentItem);\r\n\r\n return;\r\n } else {\r\n /**\r\n * If current item is not empty than split current item\r\n */\r\n this.splitItem(currentItem);\r\n }\r\n }\r\n\r\n /**\r\n * Handle backspace\r\n * @param event - keydown\r\n */\r\n private backspace(event: KeyboardEvent): void {\r\n const currentItem = this.currentItem;\r\n\r\n if (currentItem === null) {\r\n return;\r\n }\r\n\r\n /**\r\n * Caret is not at start of the item\r\n * Then backspace button should remove letter as usual\r\n */\r\n if (!isCaretAtStartOfInput(currentItem)) {\r\n return;\r\n }\r\n\r\n /**\r\n * If backspace is pressed with selection, it should be handled as usual\r\n */\r\n if (window.getSelection()?.isCollapsed === false) {\r\n return;\r\n }\r\n\r\n /**\r\n * Prevent Editor.js backspace handling\r\n */\r\n event.stopPropagation();\r\n\r\n /**\r\n * First item of the list should become paragraph on backspace\r\n */\r\n if (currentItem.parentNode === this.listWrapper && currentItem.previousElementSibling === null) {\r\n /**\r\n * If current item is first item of the list, then we need to merge first item content with previous block\r\n */\r\n this.convertFirstItemToDefaultBlock();\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * Prevent default backspace behaviour\r\n */\r\n event.preventDefault();\r\n\r\n this.mergeItemWithPrevious(currentItem);\r\n }\r\n\r\n /**\r\n * Reduce indentation for current item\r\n * @param event - keydown\r\n */\r\n private shiftTab(event: KeyboardEvent): void {\r\n /**\r\n * Prevent editor.js behaviour\r\n */\r\n event.stopPropagation();\r\n\r\n /**\r\n * Prevent browser tab behaviour\r\n */\r\n event.preventDefault();\r\n\r\n /**\r\n * Check that current item exists\r\n */\r\n if (this.currentItem === null) {\r\n return;\r\n }\r\n\r\n /**\r\n * Move item from current list to parent list\r\n */\r\n this.unshiftItem(this.currentItem);\r\n }\r\n\r\n /**\r\n * Decrease indentation of the passed item\r\n * @param item - list item to be unshifted\r\n */\r\n private unshiftItem(item: ItemElement): void {\r\n if (!item.parentNode) {\r\n return;\r\n }\r\n if (!isHtmlElement(item.parentNode)) {\r\n return;\r\n }\r\n\r\n const parentItem = item.parentNode.closest<ItemElement>(`.${DefaultListCssClasses.item}`);\r\n\r\n /**\r\n * If item in the first-level list then no need to do anything\r\n */\r\n if (!parentItem) {\r\n return;\r\n }\r\n\r\n let currentItemChildWrapper = getItemChildWrapper(item);\r\n\r\n if (item.parentElement === null) {\r\n return;\r\n }\r\n\r\n const siblings = getSiblings(item);\r\n\r\n /**\r\n * If item has any siblings, they should be appended to item child wrapper\r\n */\r\n if (siblings !== null) {\r\n /**\r\n * Render child wrapper if it does no exist\r\n */\r\n if (currentItemChildWrapper === null) {\r\n currentItemChildWrapper = this.renderer.renderWrapper(false);\r\n }\r\n\r\n /**\r\n * Append siblings to item child wrapper\r\n */\r\n siblings.forEach((sibling) => {\r\n currentItemChildWrapper!.appendChild(sibling);\r\n });\r\n\r\n item.appendChild(currentItemChildWrapper);\r\n }\r\n\r\n parentItem.after(item);\r\n\r\n focusItem(item, false);\r\n\r\n /**\r\n * If parent item has empty child wrapper after unshifting of the current item, then we need to remove child wrapper\r\n * This case could be reached if the only child item of the parent was unshifted\r\n */\r\n removeChildWrapperIfEmpty(parentItem);\r\n }\r\n\r\n /**\r\n * Method that is used for list splitting and moving trailing items to the new separated list\r\n * @param item - current item html element\r\n */\r\n private splitList(item: ItemElement): void {\r\n const currentItemChildrenList = getChildItems(item);\r\n\r\n /**\r\n * Get current list block index\r\n */\r\n const currentBlock = this.block;\r\n\r\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\r\n\r\n /**\r\n * First child item should be unshifted because separated list should start\r\n * with item with first nesting level\r\n */\r\n if (currentItemChildrenList.length !== 0) {\r\n const firstChildItem = currentItemChildrenList[0];\r\n\r\n this.unshiftItem(firstChildItem);\r\n\r\n /**\r\n * If first child item was been unshifted, that caret would be set to the end of the first child item\r\n * Then we should set caret to the actual current item\r\n */\r\n focusItem(item, false);\r\n }\r\n\r\n /**\r\n * If item is first item of the list, we should just get out of the list\r\n * It means, that we would not split on two lists, if one of them would be empty\r\n */\r\n if (item.previousElementSibling === null && item.parentNode === this.listWrapper) {\r\n this.convertItemToDefaultBlock(currentBlockIndex);\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * Get trailing siblings of the current item\r\n */\r\n const newListItems = getSiblings(item);\r\n\r\n if (newListItems === null) {\r\n return;\r\n }\r\n\r\n /**\r\n * Render new wrapper for list that would be separated\r\n */\r\n const newListWrapper = this.renderer.renderWrapper(true);\r\n\r\n /**\r\n * Append new list wrapper with trailing elements\r\n */\r\n newListItems.forEach((newListItem) => {\r\n newListWrapper.appendChild(newListItem);\r\n });\r\n\r\n const newListContent = this.save(newListWrapper);\r\n\r\n (newListContent.meta as OrderedListItemMeta).start = this.data.style == 'ordered' ? 1 : undefined;\r\n\r\n /**\r\n * Insert separated list with trailing items\r\n */\r\n this.api.blocks.insert(currentBlock?.name, newListContent, this.config, currentBlockIndex + 1);\r\n\r\n /**\r\n * Insert paragraph\r\n */\r\n this.convertItemToDefaultBlock(currentBlockIndex + 1);\r\n\r\n /**\r\n * Remove temporary new list wrapper used for content save\r\n */\r\n newListWrapper.remove();\r\n }\r\n\r\n /**\r\n * Method that is used for splitting item content and moving trailing content to the new sibling item\r\n * @param currentItem - current item html element\r\n */\r\n private splitItem(currentItem: ItemElement): void {\r\n const [currentNode, offset] = getCaretNodeAndOffset();\r\n\r\n if (currentNode === null) {\r\n return;\r\n }\r\n\r\n const currentItemContent = getItemContentElement(currentItem);\r\n\r\n let endingHTML: string;\r\n\r\n /**\r\n * If current item has no content, we should pass an empty string to the next created list item\r\n */\r\n if (currentItemContent === null) {\r\n endingHTML = '';\r\n } else {\r\n /**\r\n * On other Enters, get content from caret till the end of the block\r\n * And move it to the new item\r\n */\r\n endingHTML = getContenteditableSlice(currentItemContent, currentNode, offset, 'right', true);\r\n }\r\n\r\n const itemChildren = getItemChildWrapper(currentItem);\r\n /**\r\n * Create the new list item\r\n */\r\n const itemEl = this.renderItem(endingHTML);\r\n\r\n /**\r\n * Move new item after current\r\n */\r\n currentItem?.after(itemEl);\r\n\r\n /**\r\n * If current item has children, move them to the new item\r\n */\r\n if (itemChildren) {\r\n itemEl.appendChild(itemChildren);\r\n }\r\n\r\n focusItem(itemEl);\r\n }\r\n\r\n /**\r\n * Method that is used for merging current item with previous one\r\n * Content of the current item would be appended to the previous item\r\n * Current item children would not change nesting level\r\n * @param item - current item html element\r\n */\r\n private mergeItemWithPrevious(item: ItemElement): void {\r\n const previousItem = item.previousElementSibling;\r\n\r\n const currentItemParentNode = item.parentNode;\r\n\r\n /**\r\n * Check that parent node of the current element exists\r\n */\r\n if (currentItemParentNode === null) {\r\n return;\r\n }\r\n if (!isHtmlElement(currentItemParentNode)) {\r\n return;\r\n }\r\n\r\n const parentItem = currentItemParentNode.closest<ItemElement>(`.${DefaultListCssClasses.item}`);\r\n\r\n /**\r\n * Check that current item has any previous siblings to be merged with\r\n */\r\n if (!previousItem && !parentItem) {\r\n return;\r\n }\r\n\r\n /**\r\n * Make sure previousItem is an HTMLElement\r\n */\r\n if (previousItem && !isHtmlElement(previousItem)) {\r\n return;\r\n }\r\n\r\n /**\r\n * Lets compute the item which will be merged with current item text\r\n */\r\n let targetItem: ItemElement | null;\r\n\r\n /**\r\n * If there is a previous item then we get a deepest item in its sublists\r\n *\r\n * Otherwise we will use the parent item\r\n */\r\n if (previousItem) {\r\n /**\r\n * Get list of all levels children of the previous item\r\n */\r\n const childrenOfPreviousItem = getChildItems(previousItem, false);\r\n\r\n /**\r\n * Target item would be deepest child of the previous item or previous item itself\r\n */\r\n if (childrenOfPreviousItem.length !== 0 && childrenOfPreviousItem.length !== 0) {\r\n targetItem = childrenOfPreviousItem[childrenOfPreviousItem.length - 1];\r\n } else {\r\n targetItem = previousItem;\r\n }\r\n } else {\r\n targetItem = parentItem;\r\n }\r\n\r\n /**\r\n * Get current item content\r\n */\r\n const currentItemContent = this.renderer.getItemContent(item);\r\n\r\n /**\r\n * Get the target item content element\r\n */\r\n if (!targetItem) {\r\n return;\r\n }\r\n\r\n /**\r\n * Set caret to the end of the target item\r\n */\r\n focusItem(targetItem, false);\r\n\r\n /**\r\n * Get target item content element\r\n */\r\n const targetItemContentElement = getItemContentElement(targetItem);\r\n\r\n /**\r\n * Set a new place for caret\r\n */\r\n if (targetItemContentElement === null) {\r\n return;\r\n }\r\n\r\n /**\r\n * Update target item content by merging with current item html content\r\n */\r\n targetItemContentElement.insertAdjacentHTML('beforeend', currentItemContent);\r\n\r\n /**\r\n * Get child list of the currentItem\r\n */\r\n const currentItemChildrenList = getChildItems(item);\r\n\r\n /**\r\n * If item has no children, just remove item\r\n * Else children of the item should be prepended to the target item child list\r\n */\r\n if (currentItemChildrenList.length === 0) {\r\n /**\r\n * Remove current item element\r\n */\r\n item.remove();\r\n\r\n /**\r\n * If target item has empty child wrapper after merge, we need to remove child wrapper\r\n * This case could be reached if the only child item of the target was merged with target\r\n */\r\n removeChildWrapperIfEmpty(targetItem);\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * Get target for child list of the currentItem\r\n * Note that previous item and parent item could not be null at the same time\r\n * This case is checked before\r\n */\r\n const targetForChildItems = previousItem ? previousItem : parentItem!;\r\n\r\n const targetChildWrapper = getItemChildWrapper(targetForChildItems) ?? this.renderer.renderWrapper(false);\r\n\r\n /**\r\n * Add child current item children to the target childWrapper\r\n */\r\n if (previousItem) {\r\n currentItemChildrenList.forEach((childItem) => {\r\n targetChildWrapper.appendChild(childItem);\r\n });\r\n } else {\r\n currentItemChildrenList.forEach((childItem) => {\r\n targetChildWrapper.prepend(childItem);\r\n });\r\n }\r\n\r\n /**\r\n * If we created new wrapper, then append childWrapper to the target item\r\n */\r\n if (getItemChildWrapper(targetForChildItems) === null) {\r\n targetItem.appendChild(targetChildWrapper);\r\n }\r\n\r\n /**\r\n * Remove current item element\r\n */\r\n item.remove();\r\n }\r\n\r\n /**\r\n * Add indentation to current item\r\n * @param event - keydown\r\n */\r\n private addTab(event: KeyboardEvent): void {\r\n /**\r\n * Prevent editor.js behaviour\r\n */\r\n event.stopPropagation();\r\n\r\n /**\r\n * Prevent browser tab behaviour\r\n */\r\n event.preventDefault();\r\n\r\n const currentItem = this.currentItem;\r\n\r\n if (!currentItem) {\r\n return;\r\n }\r\n\r\n /**\r\n * Check that maxLevel specified in config\r\n */\r\n if (this.config?.maxLevel !== undefined) {\r\n const currentItemLevel = this.currentItemLevel;\r\n\r\n /**\r\n * Check that current item is not in the maximum nesting level\r\n */\r\n if (currentItemLevel !== null && currentItemLevel === this.config.maxLevel) {\r\n return;\r\n }\r\n }\r\n\r\n /**\r\n * Check that the item has potential parent\r\n * Previous sibling is potential parent in case of adding tab\r\n * After adding tab current item would be moved to the previous sibling's child list\r\n */\r\n const prevItem = currentItem.previousSibling;\r\n\r\n if (prevItem === null) {\r\n return;\r\n }\r\n if (!isHtmlElement(prevItem)) {\r\n return;\r\n }\r\n\r\n const prevItemChildrenList = getItemChildWrapper(prevItem);\r\n\r\n /**\r\n * If prev item has child items, just append current to them\r\n * Else render new child wrapper for previous item\r\n */\r\n if (prevItemChildrenList) {\r\n /**\r\n * Previous item would be appended with current item and it's sublists\r\n * After that sublists would be moved one level back\r\n */\r\n prevItemChildrenList.appendChild(currentItem);\r\n\r\n /**\r\n * Get all current item child to be moved to previous nesting level\r\n */\r\n const currentItemChildrenList = getChildItems(currentItem);\r\n\r\n /**\r\n * Move current item sublists one level back\r\n */\r\n currentItemChildrenList.forEach((child) => {\r\n prevItemChildrenList.appendChild(child);\r\n });\r\n } else {\r\n const prevItemChildrenListWrapper = this.renderer.renderWrapper(false);\r\n\r\n /**\r\n * Previous item would be appended with current item and it's sublists\r\n * After that sublists would be moved one level back\r\n */\r\n prevItemChildrenListWrapper.appendChild(currentItem);\r\n\r\n /**\r\n * Get all current item child to be moved to previous nesting level\r\n */\r\n const currentItemChildrenList = getChildItems(currentItem);\r\n\r\n /**\r\n * Move current item sublists one level back\r\n */\r\n currentItemChildrenList.forEach((child) => {\r\n prevItemChildrenListWrapper.appendChild(child);\r\n });\r\n\r\n prevItem.appendChild(prevItemChildrenListWrapper);\r\n }\r\n\r\n /**\r\n * Remove child wrapper of the current item if it is empty after adding the tab\r\n * This case would be reached, because after adding tab current item will have same nesting level with children\r\n * So its child wrapper would be empty\r\n */\r\n removeChildWrapperIfEmpty(currentItem);\r\n\r\n focusItem(currentItem, false);\r\n }\r\n\r\n /**\r\n * Convert current item to default block with passed index\r\n * @param newBloxkIndex - optional parameter represents index, where would be inseted default block\r\n * @param removeList - optional parameter, that represents condition, if List should be removed\r\n */\r\n private convertItemToDefaultBlock(newBloxkIndex?: number, removeList?: boolean): void {\r\n let newBlock;\r\n\r\n const currentItem = this.currentItem;\r\n\r\n const currentItemContent = currentItem !== null ? this.renderer.getItemContent(currentItem) : '';\r\n\r\n if (removeList === true) {\r\n this.api.blocks.delete();\r\n }\r\n\r\n /**\r\n * Check that index have passed\r\n */\r\n if (newBloxkIndex !== undefined) {\r\n newBlock = this.api.blocks.insert(undefined, { text: currentItemContent }, undefined, newBloxkIndex);\r\n } else {\r\n newBlock = this.api.blocks.insert();\r\n }\r\n\r\n currentItem?.remove();\r\n this.api.caret.setToBlock(newBlock, 'start');\r\n }\r\n\r\n /**\r\n * Convert first item of the list to default block\r\n * This method could be called when backspace button pressed at start of the first item of the list\r\n * First item of the list would be converted to the paragraph and first item children would be unshifted\r\n */\r\n private convertFirstItemToDefaultBlock(): void {\r\n const currentItem = this.currentItem;\r\n\r\n if (currentItem === null) {\r\n return;\r\n }\r\n\r\n const currentItemChildren = getChildItems(currentItem);\r\n\r\n /**\r\n * Check that current item have at least one child\r\n * If current item have no children, we can guarantee,\r\n * that after deletion of the first item of the list, children would not be removed\r\n */\r\n if (currentItemChildren.length !== 0) {\r\n const firstChildItem = currentItemChildren[0];\r\n\r\n /**\r\n * Unshift first child item, to guarantee, that after deletion of the first item\r\n * list will start with first level of nesting\r\n */\r\n this.unshiftItem(firstChildItem);\r\n\r\n /**\r\n * Set focus back to the current item after unshifting child\r\n */\r\n focusItem(currentItem);\r\n }\r\n\r\n /**\r\n * Get all first level items of the list\r\n */\r\n const currentItemSiblings = getSiblings(currentItem);\r\n\r\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\r\n\r\n /**\r\n * If current item has no siblings, than List is empty, and it should be deleted\r\n */\r\n const removeList = currentItemSiblings === null;\r\n\r\n this.convertItemToDefaultBlock(currentBlockIndex, removeList);\r\n }\r\n\r\n /**\r\n * Method that calls render function of the renderer with a necessary item meta cast\r\n * @param itemContent - content to be rendered in new item\r\n * @param meta - meta used in list item rendering\r\n * @returns html element of the rendered item\r\n */\r\n private renderItem(itemContent: ListItem['content'], meta?: ListItem['meta']): ItemElement {\r\n const itemMeta = meta ?? this.renderer.composeDefaultMeta();\r\n\r\n switch (true) {\r\n case this.renderer instanceof OrderedListRenderer:\r\n return this.renderer.renderItem(itemContent, itemMeta as OrderedListItemMeta);\r\n\r\n case this.renderer instanceof UnorderedListRenderer:\r\n return this.renderer.renderItem(itemContent, itemMeta as UnorderedListItemMeta);\r\n\r\n default:\r\n return this.renderer.renderItem(itemContent, itemMeta as ChecklistItemMeta);\r\n }\r\n }\r\n\r\n /**\r\n * Renders children list\r\n * @param items - list data used in item rendering\r\n * @param parentElement - where to append passed items\r\n */\r\n private appendItems(items: ListItem[], parentElement: Element): void {\r\n items.forEach((item) => {\r\n const itemEl = this.renderItem(item.content, item.meta);\r\n\r\n parentElement.appendChild(itemEl);\r\n\r\n /**\r\n * Check if there are child items\r\n */\r\n if (item.items.length) {\r\n const sublistWrapper = this.renderer?.renderWrapper(false);\r\n\r\n /**\r\n * Recursively render child items\r\n */\r\n this.appendItems(item.items, sublistWrapper);\r\n\r\n itemEl.appendChild(sublistWrapper);\r\n }\r\n });\r\n }\r\n}\r\n","import type { ItemElement } from '../types/Elements';\r\n\r\n/**\r\n * Check that passed item element is last item of the list\r\n * @param item - item to be checked, wherever it has next element sibling\r\n */\r\nexport function isLastItem(item: ItemElement): boolean {\r\n return item.nextElementSibling === null;\r\n}\r\n","import type { ItemElement } from '../types/Elements';\r\nimport { DefaultListCssClasses } from '../ListRenderer';\r\n\r\n/**\r\n * Check if passed item has the sublist\r\n * @param item - item to be checked wherever it has sublist\r\n */\r\nexport function itemHasSublist(item: ItemElement): boolean {\r\n return item.querySelector(`.${DefaultListCssClasses.itemChildren}`) !== null;\r\n}\r\n","import { IconNumber, IconLowerRoman, IconUpperRoman, IconLowerAlpha, IconUpperAlpha } from '../../../icons';\r\n\r\nexport type OlCounterType = 'numeric' | 'upper-roman' | 'lower-roman' | 'upper-alpha' | 'lower-alpha';\r\n\r\n/**\r\n * Map that represents all of the supported styles of the counters for ordered list\r\n */\r\nexport const OlCounterTypesMap = new Map<string, string>([\r\n /**\r\n * Value that represents default arabic numbers for counters\r\n */\r\n ['Numeric', 'numeric'],\r\n\r\n /**\r\n * Value that represents lower roman numbers for counteres\r\n */\r\n ['Lower Roman', 'lower-roman'],\r\n\r\n /**\r\n * Value that represents upper roman numbers for counters\r\n */\r\n ['Upper Roman', 'upper-roman'],\r\n\r\n /**\r\n * Value that represents lower alpha characters for counters\r\n */\r\n ['Lower Alpha', 'lower-alpha'],\r\n\r\n /**\r\n * Value that represents upper alpha characters for counters\r\n */\r\n ['Upper Alpha', 'upper-alpha'],\r\n]);\r\n\r\n/**\r\n * Map that represents relation between supported counter types and theirs icons to be displayed in toolbox\r\n */\r\nexport const OlCounterIconsMap = new Map<string, string>([\r\n /**\r\n * Value that represents Icon for Numeric counter type\r\n */\r\n ['numeric', IconNumber],\r\n\r\n /**\r\n * Value that represents Icon for Lower Roman counter type\r\n */\r\n ['lower-roman', IconLowerRoman],\r\n\r\n /**\r\n * Value that represents Icon for Upper Roman counter type\r\n */\r\n ['upper-roman', IconUpperRoman],\r\n\r\n /**\r\n * Value that represents Icon for Lower Alpha counter type\r\n */\r\n ['lower-alpha', IconLowerAlpha],\r\n\r\n /**\r\n * Value that represents Icon for Upper Alpha counter type\r\n */\r\n ['upper-alpha', IconUpperAlpha],\r\n]);\r\n","import type { API, BlockAPI, PasteConfig, ToolboxConfig } from '@ebl-vue/editorjs';\r\nimport type {\r\n BlockToolConstructorOptions,\r\n \r\n ToolConfig\r\n} from '@editorjs/editorjs/types/tools';\r\n\r\n\r\nimport type { ListConfig, ListData, ListDataStyle, ListItem, OldListData } from './types/ListParams';\r\nimport ListTabulator from './ListTabulator';\r\nimport { CheckListRenderer, OrderedListRenderer, UnorderedListRenderer } from './ListRenderer';\r\nimport type { ListRenderer } from './types/ListRenderer';\r\n\r\nimport { type OlCounterType, OlCounterTypesMap } from './types/OlCounterType';\r\n\r\nimport { IconListBulleted, IconListNumbered, IconChecklist } from \"../../icons\"; \r\n\r\n\r\n\r\n/**\r\n * Build styles\r\n */\r\nimport './styles/list.css';\r\nimport './styles/input.css';\r\n\r\nimport normalizeData from './utils/normalizeData';\r\nimport type { PasteEvent } from './types';\r\nimport type { OrderedListItemMeta } from './types/ItemMeta';\r\n\r\n/**\r\n * Constructor Params for Editorjs List Tool, use to pass initial data and settings\r\n */\r\nexport type ListParams = BlockToolConstructorOptions<ListData | OldListData, ListConfig>;\r\n\r\n/**\r\n * Default class of the component used in editor\r\n */\r\nexport default class EditorjsList {\r\n defaultCounterTypes: OlCounterType[];\r\n /**\r\n * Notify core that read-only mode is supported\r\n */\r\n public static get isReadOnlySupported(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Allow to use native Enter behaviour\r\n */\r\n public static get enableLineBreaks(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n */\r\n public static get toolbox(): ToolboxConfig {\r\n return [\r\n {\r\n icon: IconListBulleted,\r\n title: 'Unordered List',\r\n data: {\r\n style: 'unordered',\r\n },\r\n },\r\n {\r\n icon: IconListNumbered,\r\n title: 'Ordered List',\r\n data: {\r\n style: 'ordered',\r\n },\r\n },\r\n {\r\n icon: IconChecklist,\r\n title: 'Checklist',\r\n data: {\r\n style: 'checklist',\r\n },\r\n },\r\n ];\r\n }\r\n\r\n /**\r\n * On paste sanitzation config. Allow only tags that are allowed in the Tool.\r\n * @returns - paste config object used in editor\r\n */\r\n public static get pasteConfig(): PasteConfig {\r\n return {\r\n tags: ['OL', 'UL', 'LI'],\r\n };\r\n }\r\n\r\n /**\r\n * Convert from text to list with import and export list to text\r\n */\r\n public static get conversionConfig(): {\r\n /**\r\n * Method that is responsible for conversion from data to string\r\n * @param data - current list data\r\n * @returns - contents string formed from list data\r\n */\r\n export: (data: ListData) => string;\r\n\r\n /**\r\n * Method that is responsible for conversion from string to data\r\n * @param content - contents string\r\n * @returns - list data formed from contents string\r\n */\r\n import: (content: string, config: ToolConfig<ListConfig>) => ListData;\r\n } {\r\n return {\r\n export: (data) => {\r\n return EditorjsList.joinRecursive(data);\r\n },\r\n import: (content, config) => {\r\n return {\r\n meta: {},\r\n items: [\r\n {\r\n content,\r\n meta: {},\r\n items: [],\r\n },\r\n ],\r\n style: config?.defaultStyle !== undefined ? config.defaultStyle : 'unordered',\r\n };\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Get list style name\r\n */\r\n private get listStyle(): ListDataStyle {\r\n return this.data.style || this.defaultListStyle;\r\n }\r\n\r\n /**\r\n * Set list style\r\n * @param style - new style to set\r\n */\r\n private set listStyle(style: ListDataStyle) {\r\n this.data.style = style;\r\n\r\n this.changeTabulatorByStyle();\r\n\r\n /**\r\n * Create new list element\r\n */\r\n const newListElement = this.list!.render();\r\n\r\n this.listElement?.replaceWith(newListElement);\r\n\r\n this.listElement = newListElement;\r\n }\r\n\r\n /**\r\n * The Editor.js API\r\n */\r\n private api: API;\r\n\r\n /**\r\n * Is Ediotrjs List Tool read-only\r\n */\r\n private readOnly: boolean;\r\n\r\n /**\r\n * Tool's configuration\r\n */\r\n private config: ListConfig | undefined;\r\n\r\n /**\r\n * Default list style formes as passed default list style from config or 'ordered' as default\r\n */\r\n private defaultListStyle?: ListConfig['defaultStyle'];\r\n\r\n /**\r\n * Default Counter type of the ordered list\r\n */\r\n //private defaultCounterTypes: OlCounterType[];\r\n\r\n /**\r\n * Tool's data\r\n */\r\n private data: ListData;\r\n\r\n /**\r\n * Editor block api\r\n */\r\n private block: BlockAPI;\r\n\r\n /**\r\n * Class that is responsible for complete list rendering and saving\r\n */\r\n private list: ListTabulator<ListRenderer> | undefined;\r\n\r\n /**\r\n * Main constant wrapper of the whole list\r\n */\r\n private listElement: HTMLElement | undefined;\r\n\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n * @param params - tool constructor options\r\n * @param params.data - previously saved data\r\n * @param params.config - user config for Tool\r\n * @param params.api - Editor.js API\r\n * @param params.readOnly - read-only mode flag\r\n */\r\n constructor({ data, config, api, readOnly, block }: ListParams) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n this.config = config;\r\n this.block = block;\r\n\r\n /**\r\n * Set the default list style from the config or presetted 'unordered'.\r\n */\r\n this.defaultListStyle = this.config?.defaultStyle || 'unordered';\r\n\r\n /**\r\n * Set the default counter types for the ordered list\r\n */\r\n this.defaultCounterTypes = (this.config as ListConfig).counterTypes || Array.from(OlCounterTypesMap.values()) as OlCounterType[];\r\n\r\n const initialData = {\r\n style: this.defaultListStyle,\r\n meta: {},\r\n items: [],\r\n };\r\n\r\n this.data = Object.keys(data).length ? normalizeData(data) : initialData;\r\n\r\n /**\r\n * Assign default value of the property for the ordered list\r\n */\r\n if (this.listStyle === 'ordered' && (this.data.meta as OrderedListItemMeta).counterType === undefined) {\r\n (this.data.meta as OrderedListItemMeta).counterType = 'numeric';\r\n }\r\n\r\n this.changeTabulatorByStyle();\r\n }\r\n\r\n /**\r\n * Convert from list to text for conversionConfig\r\n * @param data - current data of the list\r\n * @returns - string of the recursively merged contents of the items of the list\r\n */\r\n private static joinRecursive(data: ListData | ListItem): string {\r\n return data.items\r\n .map(item => `${item.content} ${EditorjsList.joinRecursive(item)}`)\r\n .join('');\r\n }\r\n\r\n /**\r\n * Function that is responsible for content rendering\r\n * @returns rendered list wrapper with all contents\r\n */\r\n public render(): HTMLElement {\r\n this.listElement = this.list!.render();\r\n\r\n return this.listElement;\r\n }\r\n\r\n /**\r\n * Function that is responsible for content saving\r\n * @returns formatted content used in editor\r\n */\r\n public save(): ListData {\r\n this.data = this.list!.save();\r\n\r\n return this.data;\r\n }\r\n\r\n /**\r\n * Function that is responsible for mergind two lists into one\r\n * @param data - data of the next standing list, that should be merged with current\r\n */\r\n public merge(data: ListData): void {\r\n this.list!.merge(data);\r\n }\r\n\r\n /**\r\n * Creates Block Tune allowing to change the list style\r\n * @returns array of tune configs\r\n */\r\n // public renderSettings(): MenuConfigItem[] {\r\n // const defaultTunes: MenuConfigItem[] = [\r\n // {\r\n // label: this.api.i18n.t('Unordered'),\r\n // icon: IconListBulleted,\r\n // closeOnActivate: true,\r\n // isActive: this.listStyle == 'unordered',\r\n // onActivate: () => {\r\n // this.listStyle = 'unordered';\r\n // },\r\n // },\r\n // {\r\n // label: this.api.i18n.t('Ordered'),\r\n // icon: IconListNumbered,\r\n // closeOnActivate: true,\r\n // isActive: this.listStyle == 'ordered',\r\n // onActivate: () => {\r\n // this.listStyle = 'ordered';\r\n // },\r\n // },\r\n // {\r\n // label: this.api.i18n.t('Checklist'),\r\n // icon: IconChecklist,\r\n // closeOnActivate: true,\r\n // isActive: this.listStyle == 'checklist',\r\n // onActivate: () => {\r\n // this.listStyle = 'checklist';\r\n // },\r\n // },\r\n // ];\r\n\r\n // if (this.listStyle === 'ordered') {\r\n // const startWithElement = renderToolboxInput(\r\n // (index: string) => this.changeStartWith(Number(index)),\r\n // {\r\n // value: String((this.data.meta as OrderedListItemMeta).start ?? 1),\r\n // placeholder: '',\r\n // attributes: {\r\n // required: 'true',\r\n // },\r\n // sanitize: input => stripNumbers(input),\r\n // });\r\n\r\n // const orderedListTunes: MenuConfigItem[] = [\r\n // {\r\n // label: this.api.i18n.t('Start with'),\r\n // icon: IconStartWith,\r\n // children: {\r\n // items: [\r\n // {\r\n // element: startWithElement,\r\n // // @ts-expect-error ts(2820) can not use PopoverItem enum from editor.js types\r\n // type: 'html',\r\n // },\r\n // ],\r\n // },\r\n // },\r\n // ];\r\n\r\n // const orderedListCountersTunes: MenuConfigItem = {\r\n // label: this.api.i18n.t('Counter type'),\r\n // icon: OlCounterIconsMap.get((this.data.meta as OrderedListItemMeta).counterType!),\r\n // children: {\r\n // items: [],\r\n // },\r\n // };\r\n\r\n // /**\r\n // * For each counter type in OlCounterType create toolbox item\r\n // */\r\n // OlCounterTypesMap.forEach((_, counterType: string) => {\r\n // const counterTypeValue = OlCounterTypesMap.get(counterType)! as OlCounterType;\r\n\r\n // if (!this.defaultCounterTypes.includes(counterTypeValue)) {\r\n // return;\r\n // }\r\n\r\n // orderedListCountersTunes.children.items!.push({\r\n // title: this.api.i18n.t(counterType),\r\n // icon: OlCounterIconsMap.get(counterTypeValue),\r\n // isActive: (this.data.meta as OrderedListItemMeta).counterType === OlCounterTypesMap.get(counterType),\r\n // closeOnActivate: true,\r\n // onActivate: () => {\r\n // this.changeCounters(OlCounterTypesMap.get(counterType) as OlCounterType);\r\n // },\r\n // });\r\n // });\r\n\r\n // /**\r\n // * Dont show Counter type tune if there is no valid counter types\r\n // */\r\n // if (orderedListCountersTunes.children.items!.length > 1) {\r\n // orderedListTunes.push(orderedListCountersTunes);\r\n // }\r\n\r\n // // @ts-expect-error ts(2820) can not use PopoverItem enum from editor.js types\r\n // defaultTunes.push({ type: 'separator' }, ...orderedListTunes);\r\n // }\r\n\r\n // return defaultTunes;\r\n // }\r\n\r\n /**\r\n * On paste callback that is fired from Editor.\r\n * @param event - event with pasted data\r\n */\r\n public onPaste(event: PasteEvent): void {\r\n const { tagName: tag } = event.detail.data;\r\n\r\n switch (tag) {\r\n case 'OL':\r\n this.listStyle = 'ordered';\r\n break;\r\n case 'UL':\r\n case 'LI':\r\n this.listStyle = 'unordered';\r\n }\r\n\r\n this.list!.onPaste(event);\r\n }\r\n\r\n /**\r\n * Handle UL, OL and LI tags paste and returns List data\r\n * @param element - html element that contains whole list\r\n */\r\n public pasteHandler(element: PasteEvent['detail']['data']): ListData {\r\n const data = this.list!.pasteHandler(element);\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * Changes ordered list counterType property value\r\n * @param counterType - new value of the counterType value\r\n */\r\n // private changeCounters(counterType: OlCounterType): void {\r\n // this.list?.changeCounters(counterType);\r\n\r\n // (this.data.meta as OrderedListItemMeta).counterType = counterType;\r\n // }\r\n\r\n /**\r\n * Changes ordered list start property value\r\n * @param index - new value of the start property\r\n // */\r\n // private changeStartWith(index: number): void {\r\n // this.list?.changeStartWith(index);\r\n\r\n // (this.data.meta as OrderedListItemMeta).start = index;\r\n // }\r\n\r\n /**\r\n * This method allows changing tabulator respectfully to passed style\r\n */\r\n private changeTabulatorByStyle(): void {\r\n switch (this.listStyle) {\r\n case 'ordered':\r\n this.list = new ListTabulator<OrderedListRenderer>({\r\n data: this.data,\r\n readOnly: this.readOnly,\r\n api: this.api,\r\n config: this.config,\r\n block: this.block,\r\n },\r\n new OrderedListRenderer(this.readOnly, this.config)\r\n );\r\n\r\n break;\r\n\r\n case 'unordered':\r\n this.list = new ListTabulator<UnorderedListRenderer>({\r\n data: this.data,\r\n readOnly: this.readOnly,\r\n api: this.api,\r\n config: this.config,\r\n block: this.block,\r\n },\r\n new UnorderedListRenderer(this.readOnly, this.config)\r\n );\r\n\r\n break;\r\n\r\n case 'checklist':\r\n this.list = new ListTabulator<CheckListRenderer>({\r\n data: this.data,\r\n readOnly: this.readOnly,\r\n api: this.api,\r\n config: this.config,\r\n block: this.block,\r\n },\r\n new CheckListRenderer(this.readOnly, this.config)\r\n );\r\n\r\n break;\r\n }\r\n }\r\n}\r\n","import type { OldListData, ListData, ListItem, OldChecklistData, OldNestedListData } from '../types/ListParams';\r\n\r\n/**\r\n * Method that checks if data is result of the Old list tool save mtehod\r\n * @param data - data of the OldList, Checklist, OldNestedList or Editorjs List tool\r\n * @returns true if data related to the List tool, false otherwise\r\n */\r\nfunction instanceOfOldListData(data: ListData | OldListData | OldChecklistData | OldNestedListData): data is OldListData {\r\n return (typeof data.items[0] === 'string');\r\n}\r\n\r\n/**\r\n * Method that checks if data is result of the Old nested list tool save method\r\n * @param data - data of the OldList, Checklist, OldNestedList or Editorjs List tool\r\n * @returns true if data is related to the Nested List tool, false otherwise\r\n */\r\nfunction instanceOfOldNestedListData(data: ListData | OldListData | OldChecklistData | OldNestedListData): data is OldNestedListData {\r\n return !('meta' in data);\r\n}\r\n\r\n/**\r\n * Method that checks if data is result of the Old checklist tool save method\r\n * @param data - data of the Checklist, OldList, OldNestedList or Editorjs List tool\r\n * @returns true if data is related to the Checklist tool, false otherwise\r\n */\r\nfunction instanceOfChecklistData(data: ListData | OldListData | OldChecklistData | OldNestedListData): data is OldChecklistData {\r\n return (\r\n typeof data.items[0] !== 'string'\r\n && 'text' in data.items[0]\r\n && 'checked' in data.items[0]\r\n && typeof data.items[0].text === 'string'\r\n && typeof data.items[0].checked === 'boolean'\r\n );\r\n}\r\n\r\n/**\r\n * Method that checks if passed data is related to the legacy format and normalizes it\r\n * @param data - data to be checked\r\n * @returns - normalized data, ready to be used by Editorjs List tool\r\n */\r\nexport default function normalizeData(data: ListData | OldListData | OldChecklistData): ListData {\r\n\r\n const normalizedDataItems: ListItem[] = [];\r\n\r\n if (instanceOfOldListData(data)) {\r\n data.items.forEach((item) => {\r\n normalizedDataItems.push({\r\n content: item,\r\n meta: {},\r\n items: [],\r\n });\r\n });\r\n\r\n return {\r\n style: data.style,\r\n meta: {},\r\n items: normalizedDataItems,\r\n };\r\n } else if (instanceOfChecklistData(data)) {\r\n data.items.forEach((item) => {\r\n normalizedDataItems.push({\r\n content: item.text,\r\n meta: {\r\n checked: item.checked,\r\n },\r\n items: [],\r\n });\r\n });\r\n\r\n return {\r\n style: 'checklist',\r\n meta: {},\r\n items: normalizedDataItems,\r\n };\r\n } else if (instanceOfOldNestedListData(data)) {\r\n return {\r\n style: data.style,\r\n meta: {},\r\n items: data.items,\r\n };\r\n } else {\r\n return structuredClone(data);\r\n }\r\n};\r\n","/**\r\n * @typedef {Object} Observer\r\n * @description Custom MutationObserver to detect changes in the editor.\r\n * @property {String} holder — Editor.js holder id.\r\n * @property {Object} observer - MutationObserver object that detects changes in the editor.\r\n * @property {Number} debounceTimer - Delay time for the debouncer.\r\n * @property {Function} mutationDebouncer - Debouncer to delay the changes registration.\r\n */\r\nexport default class Observer {\r\n private observer: MutationObserver | null;\r\n private debounceTimer: number;\r\n private mutationDebouncer: Function;\r\n private holder: HTMLElement;\r\n /**\r\n * Creates a new instance of the Observer object.\r\n * @param {Function} registerChange - Function that register a change in the history stack.\r\n * @param {String} holder - Editor.js holder id.\r\n * @param {Number} debounceTimer Delay time for the debouncer.\r\n */\r\n constructor(registerChange: Function, holder: HTMLElement, debounceTimer: number) {\r\n\r\n this.holder = holder;\r\n this.observer = null;\r\n this.debounceTimer = debounceTimer;\r\n this.mutationDebouncer = this.debounce(() => {\r\n registerChange();\r\n }, this.debounceTimer);\r\n }\r\n\r\n /**\r\n * Sets a mutation observer to catch every change in the editor.\r\n */\r\n setMutationObserver() {\r\n const observerOptions = {\r\n childList: true,\r\n attributes: true,\r\n subtree: true,\r\n characterData: true,\r\n characterDataOldValue: true,\r\n };\r\n\r\n const target = this.holder.querySelector('.codex-editor__redactor') as HTMLElement;\r\n\r\n this.observer = new MutationObserver((mutationList) => {\r\n this.mutationHandler(mutationList);\r\n });\r\n this.observer.observe(target, observerOptions);\r\n }\r\n\r\n /**\r\n * Handles the mutations and checks if a new mutation has been produced.\r\n * @param {Object} mutationList The registered mutations\r\n */\r\n mutationHandler(mutationList: any[]) {\r\n let contentMutated = false;\r\n\r\n mutationList.forEach((mutation:any) => {\r\n switch (mutation.type) {\r\n case 'childList':\r\n if (mutation.target === this.holder) {\r\n this.onDestroy();\r\n } else {\r\n contentMutated = true;\r\n }\r\n break;\r\n case 'characterData':\r\n contentMutated = true;\r\n break;\r\n case 'attributes':\r\n if (!mutation.target.classList.contains('ce-block') && !mutation.target.classList.contains('tc-toolbox')) {\r\n contentMutated = true;\r\n }\r\n break;\r\n default:\r\n break;\r\n }\r\n });\r\n\r\n if (contentMutated) this.mutationDebouncer();\r\n }\r\n\r\n /**\r\n * Delays invoking a function until after wait millis have elapsed.\r\n * @param {Function} callback The function to be delayed.\r\n * @param {Number} wait The deplay time in millis.\r\n */\r\n debounce(callback: Function, wait: number) {\r\n let timeout: any;\r\n return (...args:any) => {\r\n const context = this;\r\n clearTimeout(timeout);\r\n timeout = setTimeout(() => callback.apply(context, args), wait);\r\n };\r\n }\r\n\r\n onDestroy() {\r\n const destroyEvent = new CustomEvent('destroy');\r\n document.dispatchEvent(destroyEvent);\r\n this.observer?.disconnect();\r\n }\r\n}\r\n","import VanillaCaret from \"vanilla-caret-js\";\r\nimport Observer from \"./observer\";\r\nimport type EditorJS from '@ebl-vue/editorjs';\r\n\r\n/**\r\n * https://github.com/kommitters/editorjs-undo/tree/main\r\n * Undo/Redo feature for Editor.js.\r\n *\r\n * @typedef {Object} Undo\r\n * @description Feature's initialization class.\r\n * @property {Object} editor — Editor.js instance object.\r\n * @property {Number} maxLength - Max amount of changes recorded by the history stack.\r\n * @property {Function} onUpdate - Callback called when the user performs an undo or redo action.\r\n * @property {Boolean} shouldSaveHistory - Defines if the plugin should save the change in the stack\r\n * @property {Object} initialItem - Initial data object.\r\n */\r\nexport default class Undo {\r\n editor: EditorJS | null;\r\n holder: any;\r\n defaultBlock: any;\r\n blocks: any;\r\n caret: any;\r\n shouldSaveHistory: boolean;\r\n readOnly: any;\r\n maxLength: any;\r\n onUpdate: any;\r\n config: { debounceTimer: any; shortcuts: { undo: any; redo: any; }; };\r\n initialItem: any;\r\n stack: any;\r\n position: number=0;\r\n /**\r\n * @param options — Plugin custom options.\r\n */\r\n constructor({ editor, config = {}, onUpdate, maxLength }:{ editor: EditorJS, config?: any, onUpdate?: any, maxLength?: any }) {\r\n const defaultOptions = {\r\n maxLength: 30,\r\n onUpdate() {},\r\n config: {\r\n debounceTimer: 200,\r\n shortcuts: {\r\n undo: [\"CMD+Z\"],\r\n redo: [\"CMD+Y\", \"CMD+SHIFT+Z\"],\r\n },\r\n },\r\n };\r\n\r\n const { blocks, caret } = editor;\r\n const { configuration } = editor;\r\n const { holder, defaultBlock } = configuration;\r\n const defaultShortcuts = defaultOptions.config.shortcuts;\r\n const { shortcuts: configShortcuts } = config;\r\n const shortcuts = { ...defaultShortcuts, ...configShortcuts };\r\n const undo = Array.isArray(shortcuts.undo) ? shortcuts.undo : [shortcuts.undo];\r\n const redo = Array.isArray(shortcuts.redo) ? shortcuts.redo : [shortcuts.redo];\r\n const defaultDebounceTimer = defaultOptions.config.debounceTimer;\r\n const { debounceTimer = defaultDebounceTimer } = config;\r\n\r\n this.holder =\r\n typeof holder === \"string\" ? document.getElementById(holder) : holder;\r\n this.editor = editor;\r\n this.defaultBlock = defaultBlock;\r\n this.blocks = blocks;\r\n this.caret = caret;\r\n this.shouldSaveHistory = true;\r\n this.readOnly = configuration.readOnly;\r\n this.maxLength = maxLength || defaultOptions.maxLength;\r\n this.onUpdate = onUpdate || defaultOptions.onUpdate;\r\n this.config = { debounceTimer, shortcuts: { undo, redo } };\r\n\r\n const observer = new Observer(\r\n () => this.registerChange(),\r\n this.holder,\r\n this.config.debounceTimer\r\n );\r\n observer.setMutationObserver();\r\n\r\n this.setEventListeners();\r\n this.initialItem = null;\r\n this.clear();\r\n }\r\n\r\n /**\r\n * Notify core that read-only mode is suppoorted\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Truncates the history stack when it excedes the limit of changes.\r\n *\r\n * @param {Object} stack Changes history stack.\r\n * @param {Number} stack Limit of changes recorded by the history stack.\r\n */\r\n truncate(stack: any, limit: number) {\r\n while (stack.length > limit) {\r\n stack.shift();\r\n }\r\n }\r\n\r\n /**\r\n * Initializes the stack when the user provides initial data.\r\n *\r\n * @param {Object} initialItem Initial data provided by the user.\r\n */\r\n initialize(initialItem: any) {\r\n const initialData =\r\n \"blocks\" in initialItem ? initialItem.blocks : initialItem;\r\n const initialIndex = initialData.length - 1;\r\n const firstElement = { index: initialIndex, state: initialData };\r\n this.stack[0] = firstElement;\r\n this.initialItem = firstElement;\r\n }\r\n\r\n /**\r\n * Clears the history stack.\r\n */\r\n clear() {\r\n this.stack = this.initialItem\r\n ? [this.initialItem]\r\n : [{ index: 0, state: [{ type: this.defaultBlock, data: {} }] }];\r\n this.position = 0;\r\n this.onUpdate();\r\n }\r\n\r\n /**\r\n * Returns true if readOnly was toggled to true\r\n * @returns {Node} Indirectly shows if readOnly was set to true or false\r\n */\r\n setReadOnly() {\r\n const toolbox = this.holder.querySelector(\".ce-toolbox\");\r\n this.readOnly = !toolbox;\r\n }\r\n\r\n /**\r\n * Registers the data returned by API's save method into the history stack.\r\n */\r\n registerChange() {\r\n this.setReadOnly();\r\n if (!this.readOnly) {\r\n if (this.editor && this.editor.save && this.shouldSaveHistory) {\r\n this.editor.save().then((savedData) => {\r\n if (this.editorDidUpdate(savedData.blocks))\r\n this.save(savedData.blocks);\r\n });\r\n }\r\n this.shouldSaveHistory = true;\r\n }\r\n }\r\n\r\n /**\r\n * Checks if the saved data has to be added to the history stack.\r\n *\r\n * @param {Object} newData New data to be saved in the history stack.\r\n * @returns {Boolean}\r\n */\r\n editorDidUpdate(newData: any) {\r\n const { state } = this.stack[this.position];\r\n if (!newData.length) return false;\r\n if (newData.length !== state.length) return true;\r\n\r\n return JSON.stringify(state) !== JSON.stringify(newData);\r\n }\r\n\r\n /**\r\n * Adds the saved data in the history stack and updates current position.\r\n */\r\n save(state: any) {\r\n if (this.position >= this.maxLength) {\r\n this.truncate(this.stack, this.maxLength);\r\n }\r\n this.position = Math.min(this.position, this.stack.length - 1);\r\n\r\n this.stack = this.stack.slice(0, this.position + 1);\r\n\r\n const index = this.blocks.getCurrentBlockIndex();\r\n const blockCount = this.blocks.getBlocksCount();\r\n let indexInState = index;\r\n\r\n if (!state[index]) indexInState -= blockCount - state.length;\r\n const caretIndex =\r\n state[indexInState] && (\r\n state[indexInState].type === \"paragraph\" ||\r\n state[indexInState].type === \"header\")\r\n ? this.getCaretIndex(index)\r\n : null;\r\n this.stack.push({ index: indexInState, state, caretIndex });\r\n this.position += 1;\r\n this.onUpdate();\r\n }\r\n\r\n /**\r\n * Gets the caret position.\r\n * @param {Number} index is the block index\r\n * @returns The caret position\r\n */\r\n getCaretIndex(index: number) {\r\n const blocks = this.holder.getElementsByClassName(\"ce-block__content\");\r\n const caretBlock = new VanillaCaret(blocks[index].firstChild);\r\n\r\n return caretBlock.getPos();\r\n }\r\n\r\n /**\r\n * Inserts a block deleted previously\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Array} compState is the state to compare and know the deleted block.\r\n * @param {Number} index is the block index in state.\r\n */\r\n insertDeletedBlock(state: any, compState: any, index: number) {\r\n for (let i = 0; i < state.length; i += 1) {\r\n if (!compState[i] || state[i].id !== compState[i].id) {\r\n this.blocks.insert(state[i].type, state[i].data, {}, i, true);\r\n this.caret.setToBlock(index, \"end\");\r\n break;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Returns true if a block was dropped previously\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Array} compState is the state to compare and know the dropped block.\r\n * @returns {Boolean} true if the block was dropped\r\n */\r\n blockWasDropped(state: any, compState: any) {\r\n if (state.length === compState.length) {\r\n return state.some((block: any, i: number) => block.id !== compState[i].id);\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Returns true if the block has to be deleted because it was skipped previously.\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Array} compState is the state to compare if there was a deleted block.\r\n * @returns {Boolean} true if a block was inserted previously.\r\n */\r\n blockWasSkipped(state: any, compState: any) {\r\n return state.length !== compState.length;\r\n }\r\n\r\n /**\r\n * Returns true if the content in a block without the focus was modified.\r\n * @param {Number} index is the block index in state.\r\n * @param {Number} compIndex is the index to compare and know if the block was inserted previously\r\n * @returns true if the content in a block without the focus was modified.\r\n */\r\n contentChangedInNoFocusBlock(index: number, compIndex: number) {\r\n return index !== compIndex;\r\n }\r\n\r\n /**\r\n * Returns true if a block was deleted previously.\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Array} compState is the state to compare and know if a block was deleted.\r\n * @returns {Boolean} true if a block was deleted previously.\r\n */\r\n blockWasDeleted(state: any, compState: any) {\r\n return state.length > compState.length;\r\n }\r\n\r\n /**\r\n * Returns true if the content was copied.\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Array} compState is the state to compare and know if the content was copied.\r\n * @param {Number} index is the block index in state.\r\n * @returns {Boolean} true if a block was deleted previously.\r\n */\r\n contentWasCopied(state: any, compState: any, index: number) {\r\n return Object.keys(state[index].data).length === 0\r\n && JSON.stringify(compState[index + 1]) !== JSON.stringify(state[index + 1]);\r\n }\r\n\r\n /**\r\n * Decreases the current position and update the respective block in the editor.\r\n */\r\n async undo() {\r\n if (this.canUndo()) {\r\n const { index: nextIndex, state: nextState } = this.stack[this.position];\r\n\r\n this.position -= 1;\r\n this.shouldSaveHistory = false;\r\n let { index } = this.stack[this.position];\r\n const { state, caretIndex } = this.stack[this.position];\r\n\r\n this.onUpdate();\r\n const blockCount = this.blocks.getBlocksCount();\r\n\r\n if (!state[index]) {\r\n index -= 1;\r\n this.stack[this.position].index = index;\r\n }\r\n\r\n if (this.blockWasDeleted(state, nextState)) {\r\n this.insertDeletedBlock(state, nextState, index);\r\n } else if (this.contentWasCopied(state, nextState, index)) {\r\n await this.blocks.render({ blocks: state });\r\n this.caret.setToBlock(index, 'end');\r\n } else if (index < nextIndex && this.blockWasSkipped(state, nextState)) {\r\n await this.blocks.delete(nextIndex);\r\n this.caret.setToBlock(index, \"end\");\r\n } else if (blockCount > state.length) {\r\n await this.blocks.render({ blocks: state });\r\n this.setCaretIndex(index, caretIndex);\r\n } else if (this.blockWasDropped(state, nextState)) {\r\n await this.blocks.render({ blocks: state });\r\n this.caret.setToBlock(index, 'end');\r\n } else if (this.contentChangedInNoFocusBlock(index, nextIndex)) {\r\n const { id } = this.blocks.getBlockByIndex(nextIndex);\r\n\r\n await this.blocks.update(id, state[nextIndex].data);\r\n this.setCaretIndex(index, caretIndex);\r\n }\r\n\r\n const block = this.blocks.getBlockByIndex(index);\r\n if (block) {\r\n await this.blocks.update(block.id, state[index].data);\r\n this.setCaretIndex(index, caretIndex);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Sets the caret position.\r\n * @param {Number} index is the block index\r\n * @param {Number} caretIndex is the caret position\r\n * @param {Array} state is the current state according to this.position.\r\n */\r\n setCaretIndex(index: number, caretIndex: number) {\r\n if (caretIndex && caretIndex !== -1) {\r\n const blocks = this.holder.getElementsByClassName(\"ce-block__content\");\r\n const caretBlock = new VanillaCaret(blocks[index].firstChild);\r\n setTimeout(() => caretBlock.setPos(caretIndex), 50);\r\n } else {\r\n this.caret.setToBlock(index, \"end\");\r\n }\r\n }\r\n\r\n /**\r\n * Inserts new block\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Number} index is the block index\r\n */\r\n async insertBlock(state: any, index: number) {\r\n await this.blocks.insert(\r\n state[index].type,\r\n state[index].data,\r\n {},\r\n index,\r\n true,\r\n );\r\n }\r\n\r\n /**\r\n * Inserts a block when is skipped and update the previous one if it changed.\r\n * @param {Array} prevState is the previous state according to this.position.\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Number} index is the block index.\r\n */\r\n async insertSkippedBlocks(prevState: any, state: any, index: number) {\r\n for (let i = prevState.length; i < state.length; i += 1) {\r\n this.insertBlock(state, i);\r\n }\r\n\r\n if (JSON.stringify(prevState[index - 1]) !== JSON.stringify(state[index - 1])) {\r\n await this.updateModifiedBlock(state, index);\r\n }\r\n }\r\n\r\n /**\r\n * Updates the passed block or render the state when the content was copied.\r\n * @param {Array} state is the current state according to this.position.\r\n * @param {Number} index is the block index.\r\n */\r\n async updateModifiedBlock(state: any, index: number) {\r\n const block = state[index - 1];\r\n if (this.editor!.blocks.getById(block.id)) return this.blocks.update(block.id, block.data);\r\n return this.blocks.render({ blocks: state });\r\n }\r\n\r\n /**\r\n * Increases the current position and update the respective block in the editor.\r\n */\r\n async redo() {\r\n if (this.canRedo()) {\r\n this.position += 1;\r\n this.shouldSaveHistory = false;\r\n const { index, state, caretIndex } = this.stack[(this.position)];\r\n const { index:prevIndex, state: prevState } =\r\n this.stack[this.position - 1];\r\n\r\n if (this.blockWasDeleted(prevState, state)) {\r\n await this.blocks.delete();\r\n this.caret.setToBlock(index, \"end\");\r\n } else if (this.blockWasSkipped(state, prevState)) {\r\n await this.insertSkippedBlocks(prevState, state, index);\r\n this.caret.setToBlock(index, 'end');\r\n } else if (this.blockWasDropped(state, prevState) && this.position !== 1) {\r\n await this.blocks.render({ blocks: state });\r\n this.caret.setToBlock(index, \"end\");\r\n }\r\n\r\n this.onUpdate();\r\n const block = this.blocks.getBlockByIndex(index);\r\n if (block) {\r\n await this.blocks.update(block.id, state[index].data);\r\n this.setCaretIndex(index, caretIndex);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Checks if the history stack can perform an undo action.\r\n *\r\n * @returns {Boolean}\r\n */\r\n canUndo() {\r\n return !this.readOnly && this.position > 0;\r\n }\r\n\r\n /**\r\n * Checks if the history stack can perform a redo action.\r\n *\r\n * @returns {Boolean}\r\n */\r\n canRedo() {\r\n return !this.readOnly && this.position < this.count();\r\n }\r\n\r\n /**\r\n * Returns the number of changes recorded in the history stack.\r\n *\r\n * @returns {Number}\r\n */\r\n count() {\r\n return this.stack.length - 1; // -1 because of initial item\r\n }\r\n\r\n /**\r\n * Parses the keys passed in the shortcut property to accept CMD,ALT and SHIFT\r\n *\r\n * @param {Array} keys are the keys passed in shortcuts in config\r\n * @returns {Array}\r\n */\r\n\r\n parseKeys(keys: string[]) {\r\n const specialKeys: any = {\r\n CMD: /(Mac)/i.test(navigator.platform) ? \"metaKey\" : \"ctrlKey\",\r\n ALT: \"altKey\",\r\n SHIFT: \"shiftKey\",\r\n };\r\n const parsedKeys = keys.slice(0, -1).map((key) => specialKeys[key]);\r\n\r\n const letterKey =\r\n parsedKeys.includes(\"shiftKey\") && keys.length === 2\r\n ? keys[keys.length - 1].toUpperCase()\r\n : keys[keys.length - 1].toLowerCase();\r\n\r\n parsedKeys.push(letterKey);\r\n return parsedKeys;\r\n }\r\n\r\n /**\r\n * Sets events listeners to allow keyboard actions support\r\n */\r\n\r\n setEventListeners() {\r\n const { holder } = this;\r\n const { shortcuts } = this.config;\r\n const { undo, redo } = shortcuts;\r\n const keysUndo = undo.map((undoShortcut: string) => undoShortcut.replace(/ /g, \"\").split(\"+\"));\r\n const keysRedo = redo.map((redoShortcut: string) => redoShortcut.replace(/ /g, \"\").split(\"+\"));\r\n\r\n const keysUndoParsed = keysUndo.map((keys: string[]) => this.parseKeys(keys));\r\n const keysRedoParsed = keysRedo.map((keys: string[]) => this.parseKeys(keys));\r\n\r\n const twoKeysPressed = (e: any, keys: any) => {\r\n return keys.length === 2 && e[keys[0]] && (e.key.toLowerCase() === keys[1]);\r\n }\r\n const threeKeysPressed = (e: any, keys: any) => {\r\n return keys.length === 3 && e[keys[0]] && e[keys[1]] && (e.key.toLowerCase() === keys[2]);\r\n }\r\n const verifyListTwoKeysPressed = (e: KeyboardEvent, keysList:string[]) =>\r\n keysList.reduce((result, keys:string) => result || twoKeysPressed(e, keys), false);\r\n const verifyListThreeKeysPressed = (e: KeyboardEvent, keysList:string[]) =>\r\n keysList.reduce((result, keys) => result || threeKeysPressed(e, keys), false);\r\n\r\n const pressedKeys = (e: KeyboardEvent, keys: string[], compKeys: string[]) => {\r\n if (verifyListTwoKeysPressed(e, keys) && !verifyListThreeKeysPressed(e, compKeys)) {\r\n return true;\r\n }\r\n if (verifyListThreeKeysPressed(e, keys)) {\r\n return true;\r\n }\r\n return false;\r\n };\r\n\r\n const handleUndo = (e: KeyboardEvent) => {\r\n if (pressedKeys(e, keysUndoParsed, keysRedoParsed)) {\r\n e.preventDefault();\r\n this.undo();\r\n }\r\n };\r\n\r\n const handleRedo = (e: KeyboardEvent) => {\r\n if (pressedKeys(e, keysRedoParsed, keysUndoParsed)) {\r\n e.preventDefault();\r\n this.redo();\r\n }\r\n };\r\n\r\n const handleDestroy = () => {\r\n holder.removeEventListener(\"keydown\", handleUndo);\r\n holder.removeEventListener(\"keydown\", handleRedo);\r\n };\r\n\r\n holder.addEventListener(\"keydown\", handleUndo);\r\n holder.addEventListener(\"keydown\", handleRedo);\r\n holder.addEventListener(\"destroy\", handleDestroy);\r\n }\r\n}\r\n","/**\r\n * Alert block for the Editor.js.\r\n *\r\n * @author Vishal Telangre\r\n * @license MIT\r\n */\r\n\r\n/**\r\n * Build styles\r\n */\r\n\r\nimport type { API,BlockTool,BlockToolConstructorOptions } from \"@ebl-vue/editorjs/types\";\r\nimport './index.css';\r\nimport type { HTMLPasteEvent } from '@ebl-vue/editorjs';\r\nimport { IconToolboxAlert as ToolboxIcon,IconAlignLeft as AlignLeftIcon,IconAlignCenter as AlignCenterIcon,IconAlignRight as AlignRightIcon } from \"../../icons\";\r\n\r\n\r\n/**\r\n * @class Alert\r\n * @classdesc Alert Tool for Editor.js\r\n * @property {AlertData} data - Alert Tool`s input and output data\r\n * @property {object} api - Editor.js API instance\r\n *\r\n * @typedef {object} AlertData\r\n * @description Alert Tool`s input and output data\r\n * @property {string} type - Alert type\r\n * @property {string} alignType - Alert align type\r\n * @property {string} message - Alert message\r\n *\r\n * @typedef {object} AlertConfig\r\n * @description Alert Tool`s initial configuration\r\n * @property {string} defaultType - default Alert type\r\n * @property {string} defaultAlignType - default align Alert type\r\n * @property {string} messagePlaceholder - placeholder to show in Alert`s message input\r\n */\r\nexport default class Alert implements BlockTool{\r\n /**\r\n * Get Toolbox settings\r\n *\r\n * @public\r\n * @returns {string}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: ToolboxIcon,\r\n title: 'Alert',\r\n };\r\n }\r\n\r\n /**\r\n * Allow to press Enter inside the Alert block\r\n * @public\r\n * @returns {boolean}\r\n */\r\n static get enableLineBreaks() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Default Alert type\r\n *\r\n * @public\r\n * @returns {string}\r\n */\r\n static get DEFAULT_TYPE() {\r\n return 'info';\r\n }\r\n\r\n /**\r\n * Default Alert align type\r\n *\r\n * @public\r\n * @returns {string}\r\n */\r\n static get DEFAULT_ALIGN_TYPE() {\r\n return 'left';\r\n }\r\n\r\n /**\r\n * Default placeholder for Alert message\r\n *\r\n * @public\r\n * @returns {string}\r\n */\r\n static get DEFAULT_MESSAGE_PLACEHOLDER() {\r\n return 'Type here...';\r\n }\r\n\r\n /**\r\n * Supported Alert types\r\n *\r\n * @public\r\n * @returns {array}\r\n */\r\n static get ALERT_TYPES() {\r\n return [\r\n 'primary',\r\n 'secondary',\r\n 'info',\r\n 'success',\r\n 'warning',\r\n 'danger',\r\n 'light',\r\n 'dark',\r\n ];\r\n }\r\n\r\n /**\r\n * Supported Align types\r\n *\r\n * @public\r\n * @returns {array}\r\n */\r\n static get ALIGN_TYPES() {\r\n return ['left', 'center', 'right'];\r\n }\r\n\r\n /**\r\n * Alert Tool`s styles\r\n *\r\n * @returns {Object}\r\n */\r\n get CSS() {\r\n return {\r\n wrapper: 'cdx-alert',\r\n wrapperForType: (type:string) => `cdx-alert-${type}`,\r\n wrapperForAlignType: (alignType:string) => `cdx-alert-align-${alignType}`,\r\n message: 'cdx-alert__message',\r\n };\r\n }\r\n private alertTypes: string[];\r\n private defaultType: string;\r\n private defaultAlign: string;\r\n private messagePlaceholder: string;\r\n private data: any;\r\n private api: API;\r\n private container: any;\r\n private readOnly: boolean;\r\n\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {AlertData} data — previously saved data\r\n * @param {AlertConfig} config — user config for Tool\r\n * @param {Object} api - Editor.js API\r\n * @param {boolean} readOnly - read only mode flag\r\n */\r\n constructor({ data, config, api, readOnly }:BlockToolConstructorOptions) {\r\n this.api = api;\r\n\r\n this.alertTypes = config.alertTypes || Alert.ALERT_TYPES;\r\n this.defaultType = config.defaultType || Alert.DEFAULT_TYPE;\r\n this.defaultAlign = config.defaultAlign || Alert.DEFAULT_ALIGN_TYPE;\r\n this.messagePlaceholder =\r\n config.messagePlaceholder || Alert.DEFAULT_MESSAGE_PLACEHOLDER;\r\n\r\n this.data = {\r\n type: this.alertTypes.includes(data.type)\r\n ? data.type\r\n : this.defaultType,\r\n align: Alert.ALIGN_TYPES.includes(data.align)\r\n ? data.align\r\n : this.defaultAlign,\r\n message: data.message || '',\r\n };\r\n\r\n this.container = undefined;\r\n\r\n this.readOnly = readOnly;\r\n }\r\n\r\n /**\r\n * Returns true to notify the core that read-only mode is supported\r\n *\r\n * @return {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Create Alert Tool container\r\n *\r\n * @returns {Element}\r\n */\r\n render() {\r\n const containerClasses = [\r\n this.CSS.wrapper,\r\n this.CSS.wrapperForType(this.data.type),\r\n this.CSS.wrapperForAlignType(this.data.align),\r\n ];\r\n\r\n this.container = this._make('div', containerClasses);\r\n\r\n const messageEl = this._make('div', [this.CSS.message], {\r\n contentEditable: !this.readOnly,\r\n innerHTML: this.data.message,\r\n });\r\n\r\n messageEl.dataset.placeholder = this.messagePlaceholder;\r\n\r\n this.container.appendChild(messageEl);\r\n\r\n return this.container;\r\n }\r\n _getSettingIconStyle(type: string) {\r\n let classname = \"\";\r\n switch (type) {\r\n case 'primary':\r\n classname = \"cdx-alert-primary\";\r\n break;\r\n case 'secondary':\r\n classname = \"cdx-alert-secondary\";\r\n break;\r\n case 'info':\r\n classname = \"cdx-alert-info\";\r\n break;\r\n case 'success':\r\n classname = \"cdx-alert-success\";\r\n break;\r\n case 'warning':\r\n classname = \"cdx-alert-warning\";\r\n break;\r\n case 'danger':\r\n classname = \"cdx-alert-danger\";\r\n break;\r\n case 'light':\r\n classname = \"cdx-alert-light\";\r\n break;\r\n case 'dark':\r\n classname = \"cdx-alert-dark\";\r\n break;\r\n }\r\n const iconWrap = this._make('div', ['cdx-alert_setting__icon',classname], {});\r\n return iconWrap;\r\n }\r\n \r\n /**\r\n * Create Block's settings block\r\n *\r\n * @returns {array}\r\n */\r\n renderSettings() {\r\n const wrapper = document.createElement('div');\r\n const alertWrapper = document.createElement('div');\r\n const alignWrapper= document.createElement('div');\r\n alertWrapper.classList.add('cdx-alert_setting__icon_wrapper');\r\n alignWrapper.classList.add('cdx-alert_setting__icon_wrapper');\r\n alignWrapper.classList.add(\"cdx-alert_setting__icon_wrapper_align\");\r\n\r\n this.alertTypes.map((type) => {\r\n let button = this._getSettingIconStyle(type);\r\n button.setAttribute('data-type', type);\r\n\r\n this.api.tooltip.onHover(button, this.api.i18n.t(`alert-${type}`), {\r\n placement: 'top',\r\n }); \r\n button.innerText = \"A\";\r\n alertWrapper.appendChild(button);\r\n return button;\r\n }).forEach((button, index, buttons) => { \r\n const type: string = button.getAttribute('data-type') || \"\";\r\n button.addEventListener('click', () => {\r\n this._changeAlertType(type);\r\n buttons.forEach((el, index) => {\r\n const elType= el.getAttribute('data-type');\r\n el.classList.toggle(\"cdx-alert_setting__icon_active\", elType === this.data.type);\r\n });\r\n });\r\n \r\n\r\n });\r\n\r\n\r\n Alert.ALIGN_TYPES.map((align) => {\r\n let button;\r\n if (align === \"left\") {\r\n button = document.createElement(\"div\");\r\n button.classList.add(\"cdx-alert_setting__icon\");\r\n button.innerHTML = AlignLeftIcon;\r\n }\r\n if (align === \"right\") {\r\n button = document.createElement(\"div\");\r\n button.classList.add(\"cdx-alert_setting__icon\");\r\n button.innerHTML = AlignRightIcon;\r\n\r\n }\r\n if (align === \"center\") {\r\n button = document.createElement(\"div\");\r\n button.classList.add(\"cdx-alert_setting__icon\");\r\n button.innerHTML = AlignCenterIcon;\r\n\r\n\r\n }\r\n\r\n button?.setAttribute(\"data-align\", align);\r\n this.api.tooltip.onHover(button!, this.api.i18n.t(`align-${align}`), {\r\n placement: 'top',\r\n });\r\n alignWrapper.appendChild(button!);\r\n return button;\r\n }).forEach((button, index, buttons) => {\r\n const align: string = button!.getAttribute('data-align') || \"\";\r\n button!.addEventListener('click', () => {\r\n this._changeAlignType(align);\r\n buttons.forEach((el, index) => {\r\n const elAlign = el?.getAttribute('data-align');\r\n el?.classList.toggle(\"cdx-alert_setting__icon_active\", elAlign === this.data.align);\r\n });\r\n });\r\n });\r\n\r\n wrapper.appendChild(alertWrapper);\r\n wrapper.appendChild(alignWrapper);\r\n return wrapper;\r\n }\r\n\r\n /**\r\n * Helper for formatting Alert Type / Align Type\r\n *\r\n * @param {string} type - Alert type or Align type\r\n * @returns {string}\r\n */\r\n _getFormattedName(name: string) {\r\n return this.api.i18n.t(name.charAt(0).toUpperCase() + name.slice(1));\r\n }\r\n\r\n /**\r\n * Helper for changing style of Alert block with the selected Alert type\r\n *\r\n * @param {string} newType - new Alert type to be applied to the block\r\n * @private\r\n */\r\n _changeAlertType(newType: string) {\r\n // Save new type\r\n this.data.type = newType;\r\n\r\n this.alertTypes.forEach((type) => {\r\n const alertClass = this.CSS.wrapperForType(type);\r\n\r\n // Remove the old Alert type class\r\n this.container.classList.remove(alertClass);\r\n\r\n if (newType === type) {\r\n // Add an Alert class for the selected Alert type\r\n this.container.classList.add(alertClass);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Helper for changing align of Alert block with the selected Align type\r\n *\r\n * @param {string} newAlign - new align type to be applied to the block\r\n * @private\r\n */\r\n _changeAlignType(newAlign: string) {\r\n // Save new type\r\n this.data.align = newAlign;\r\n\r\n Alert.ALIGN_TYPES.forEach((align) => {\r\n const alignClass = this.CSS.wrapperForAlignType(align);\r\n\r\n // Remove the old Alert type class\r\n this.container.classList.remove(alignClass);\r\n\r\n if (newAlign === align) {\r\n // Add an Alert class for the selected Alert type\r\n this.container.classList.add(alignClass);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Extract Alert data from Alert Tool element\r\n *\r\n * @param {HTMLDivElement} alertElement - element to save\r\n * @returns {AlertData}\r\n */\r\n save(alertElement: HTMLElement) {\r\n const messageEl = alertElement.querySelector(`.${this.CSS.message}`);\r\n\r\n return { ...this.data, message: messageEl?.innerHTML || '' };\r\n }\r\n\r\n /**\r\n * Helper for making Elements with attributes\r\n *\r\n * @param {string} tagName - new Element tag name\r\n * @param {array|string} classNames - list or name of CSS classname(s)\r\n * @param {Object} attributes - any attributes\r\n * @returns {Element}\r\n * @private\r\n */\r\n _make(tagName:string, classNames:string[]|string|null, attributes:Record<string, any> = {}) {\r\n let el = document.createElement(tagName);\r\n\r\n if (Array.isArray(classNames)) {\r\n el.classList.add(...classNames);\r\n } else if (classNames) {\r\n el.classList.add(classNames);\r\n }\r\n\r\n for (let attrName in attributes) {\r\n //el[attrName] = attributes[attrName];\r\n el.setAttribute(attrName, attributes[attrName]);\r\n }\r\n\r\n return el;\r\n }\r\n\r\n /**\r\n * Fill Alert's message with the pasted content\r\n *\r\n * @param {PasteEvent} event - event with pasted content\r\n */\r\n onPaste(event:HTMLPasteEvent) {\r\n const { data } = event.detail;\r\n\r\n this.data = {\r\n type: this.defaultType,\r\n message: data.innerHTML || '',\r\n };\r\n }\r\n\r\n /**\r\n * Allow Alert to be converted to/from other blocks\r\n */\r\n static get conversionConfig() {\r\n return {\r\n // export Alert's message for other blocks\r\n export: (data:any) => data.message,\r\n // fill Alert's message from other block's export string\r\n import: (string:string) => {\r\n return {\r\n message: string,\r\n type: this.DEFAULT_TYPE,\r\n alignType: this.DEFAULT_ALIGN_TYPE,\r\n };\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Sanitizer config for Alert Tool saved data\r\n * @returns {Object}\r\n */\r\n static get sanitize() {\r\n return {\r\n message: true,\r\n type: false,\r\n alignType: false,\r\n };\r\n }\r\n}\r\n","import type { BlockTune, API, BlockAPI, BlockAddedEvent,ToolConfig } from '@ebl-vue/editorjs/types'\r\n\r\nimport type { MenuConfig } from '@ebl-vue/editorjs/types/tools'\r\nimport { IconIndentLeft,IconIndentRight } from '../../icons';\r\n\r\nimport './index.css'\r\n\r\n\r\n\r\ninterface ConstructorArgs {\r\n data: IndentData;\r\n config?: ToolConfig;\r\n api: API;\r\n block?: any;\r\n}\r\nexport type TextDirection = 'ltr' | \"rtl\"\r\n\r\nexport type IndentTuneConfig = Partial<IndentTuneConfigOptions>\r\nexport type IndentTuneConfigOptions = Record<'indentSize' | 'maxIndent' | 'minIndent', number> & {\r\n /**\r\n * Specify the editorjs version so that the styles will match your version\r\n */\r\n version?: string;\r\n /**\r\n * Enables auto indent if not null or `true`\r\n * Default disabled.\r\n */\r\n autoIndent?: {\r\n /**\r\n * Tunes you want to apply auto indent for.\r\n * Defaults to all.\r\n */\r\n tuneNames?: string[]\r\n } | boolean;\r\n /**\r\n * Apply a highlight to the indent if not null\r\n */\r\n highlightIndent?: {\r\n className?: string,\r\n /**\r\n * Tunes you want to apply highlight for.\r\n * Defaults to all.\r\n */\r\n tuneNames?: string[]\r\n };\r\n orientation: 'horizontal' | 'vertical';\r\n /**\r\n * Example:\r\n * {\r\n * tableTuneName: { min: 2, max:8 },\r\n * imageTuneName: { min:1 }\r\n * }\r\n */\r\n customBlockIndentLimits: Record<string, Partial<Record<'min' | 'max', number>>>;\r\n /**\r\n * Custom keyboard indent handler.\r\n * Return 'indent' or 'unindent' if you want to change the current indentation.\r\n * Return 'undefined' or pass 'false' instead of a function to disable the shortcut entirely\r\n * Return 'default' for default handling\r\n */\r\n handleShortcut?: ((e: KeyboardEvent, blockId: string) => 'indent' | 'unindent' | \"default\" | undefined) | undefined | false;\r\n /**\r\n * `ltr` | `rtl`\r\n */\r\n direction: TextDirection;\r\n /**\r\n * Handle dynamic direction change (on each block level)\r\n */\r\n directionChangeHandler: null | ((listener: (blockId: string, direction: TextDirection) => void) => void);\r\n} & (\r\n | {\r\n tuneName: string\r\n multiblock: true\r\n }\r\n | {\r\n tuneName: null\r\n multiblock: false\r\n }\r\n )\r\nconst warnings = { orientation: false };\r\nexport type IndentData = { indentLevel: number }\r\nexport default class IndentTune implements BlockTune {\r\n public static get isTune() {\r\n return true\r\n }\r\n public static DATA_WRAPPER_NAME = 'data-block-indent-wrapper'\r\n public static DATA_FOCUSED = 'data-focused'\r\n public static DATA_INDENT_LEVEL = \"data-indent-level\"\r\n private api: API\r\n private block: BlockAPI | undefined\r\n private config: IndentTuneConfigOptions\r\n public data: IndentData\r\n private wrapper: HTMLElement = document.createElement('div')\r\n private DEFAULT_INDENT_KEY = 'Tab' as const;\r\n constructor({ api, data, config, block, ...other }: ConstructorArgs) {\r\n this.api = api\r\n this.block = block\r\n\r\n const defaultConfig: IndentTuneConfigOptions = {\r\n indentSize: 24,\r\n maxIndent: 8,\r\n minIndent: 0,\r\n multiblock: false,\r\n autoIndent: false,\r\n tuneName: null,\r\n orientation: 'horizontal',\r\n customBlockIndentLimits: {},\r\n handleShortcut: undefined,\r\n direction: \"ltr\",\r\n directionChangeHandler: null,\r\n version: \"2.30\",\r\n }\r\n if (!config && \"settings\" in other)\r\n // for older versions\r\n config = other.settings as any ?? {}\r\n this.config = {\r\n ...defaultConfig,\r\n ...(config ?? {}),\r\n }\r\n\r\n this.changeConfigBasedOnVersionIfNeeded();\r\n\r\n if (this.config?.directionChangeHandler) {\r\n this.config.directionChangeHandler(this.alignmentChangeListener.bind(this));\r\n }\r\n\r\n const defaultIndentLevel = this.config.customBlockIndentLimits[this.block?.name ?? '']?.min ?? this.config.minIndent\r\n this.data = {\r\n //@ts-ignore\r\n indentLevel: defaultIndentLevel,\r\n ...(data ?? {}),\r\n }\r\n\r\n if (this.config.multiblock && !this.config.tuneName)\r\n console.error(\"IndentTune config 'tuneName' was not provided, this is required for multiblock option to work.\")\r\n\r\n window.addEventListener('resize', (e) => this.onResize.call(this, e))\r\n\r\n // this is called after the indent tune constructor is created\r\n this.api.events.on(\"block changed\", ({ event }: { event: BlockAddedEvent }) => {\r\n const targetId = event.detail.target.id;\r\n const currentBlockId = this.block?.id;\r\n const isSameTarget = currentBlockId === targetId\r\n if (!isSameTarget) return;\r\n\r\n if (!this.shouldApplyAutoIndent) return\r\n queueMicrotask(() => this.autoIndentBlock())\r\n })\r\n }\r\n\r\n\r\n public prepare?(): void | Promise<void> {\r\n\r\n }\r\n public reset?(): void | Promise<void> {\r\n\r\n }\r\n\r\n\r\n public render(): HTMLElement | MenuConfig {\r\n //Disable items after they are rendered synchronously\r\n const disableItemOnRender = () => {\r\n if (this.data.indentLevel == this.maxIndent) {\r\n const element = this.getTuneButton('indent');\r\n element?.classList.add(this.CSS.disabledItem)\r\n if (!element) return true;\r\n\r\n }\r\n if (this.data.indentLevel == this.minIndent) {\r\n const element = this.getTuneButton('unindent');\r\n element?.classList.add(this.CSS.disabledItem)\r\n if (!element) return true;\r\n }\r\n }\r\n queueMicrotask(() => {\r\n const shouldUseMacroTask = disableItemOnRender();\r\n if (shouldUseMacroTask)\r\n setTimeout(disableItemOnRender, 300)\r\n })\r\n\r\n\r\n if (this.config.orientation === 'vertical') {\r\n const leftElementName = `${this.TuneNames.indentLeft}-${this.block?.id}`;\r\n const rightElementName = `${this.TuneNames.indentRight}-${this.block?.id}`\r\n return [\r\n {\r\n title: this.rightText,\r\n hint: {\r\n title: this.api.i18n.t(this.rightText),\r\n },\r\n onActivate: (item, event) => {\r\n this.handleIndentRight();\r\n // override editorjs internal title copy\r\n //@ts-ignore\r\n item.title = this.rightText;\r\n },\r\n icon: IconIndentRight,\r\n name: rightElementName,\r\n },\r\n {\r\n title: this.leftText,\r\n hint: {\r\n title: this.api.i18n.t(this.leftText),\r\n },\r\n onActivate: (item, event) => {\r\n this.handleIndentLeft()\r\n //@ts-ignore\r\n item.title = this.leftText;\r\n },\r\n icon: IconIndentLeft,\r\n name: leftElementName,\r\n },\r\n ]\r\n }\r\n\r\n const html = /*html*/ `\r\n\t\t\t<div class=\"${this.CSS.popoverItem} ${this.CSS.customPopoverItem}\" data-item-name='indent' version=${this.config.version}>\r\n\t\t\t\t<button type=\"button\" class=\"${this.CSS.popoverItemIcon}\" data-${this.TuneNames.indentLeft}>${IconIndentLeft}</button>\r\n\t\t\t\t<span class=\"${this.CSS.popoverItemTitle}\">${this.api.sanitizer.clean(this.api.i18n.t('Indent'), {})}</span>\r\n\t\t\t\t<button type=\"button\" class=\"${this.CSS.popoverItemIcon}\" data-${this.TuneNames.indentRight} style=\"margin-left:10px;\">${IconIndentRight}</button>\r\n\t\t\t</div>\r\n\t\t`\r\n\r\n const item = this.createElementFromTemplate(html);\r\n const rightBtn = item.querySelector(`[data-${this.TuneNames.indentRight}]`);\r\n const leftBtn = item.querySelector(`[data-${this.TuneNames.indentLeft}]`);\r\n if (rightBtn) {\r\n rightBtn.addEventListener('click', () => this.handleIndentRight());\r\n this.api.tooltip.onHover(rightBtn as HTMLElement, this.api.i18n.t('Indent right'), {\r\n placement: 'top',\r\n });\r\n }\r\n if (leftBtn) {\r\n leftBtn.addEventListener('click', () => this.handleIndentLeft());\r\n this.api.tooltip.onHover(leftBtn as HTMLElement, this.api.i18n.t('Indent left'), {\r\n placement: 'top',\r\n });\r\n }\r\n return item\r\n }\r\n\r\n public wrap(pluginsContent: HTMLElement): HTMLElement {\r\n this.wrapper.appendChild(pluginsContent)\r\n this.wrapper.setAttribute(IndentTune.DATA_WRAPPER_NAME, '')\r\n\r\n let applyBlockHighlight = Boolean(this.config.highlightIndent)\r\n if (this.config.highlightIndent?.tuneNames) {\r\n const shouldIgnoreThisBlock = !this.config.highlightIndent.tuneNames.includes(this.block?.name ?? \"\")\r\n if (shouldIgnoreThisBlock)\r\n applyBlockHighlight = false\r\n }\r\n if (applyBlockHighlight) {\r\n const highlightEl = this.createElementFromTemplate(/*html*/`\r\n <div class=\"${this.config.highlightIndent?.className ?? \"\"} ${this.CSS.highlightIndent}\">\r\n </div>\r\n `);\r\n const contentEl = pluginsContent.classList.contains(this.EditorCSS.content) ? pluginsContent : pluginsContent.querySelector(`.${this.EditorCSS.content}`)\r\n contentEl?.appendChild(highlightEl);\r\n }\r\n\r\n this.applyStylesToWrapper(this.wrapper, this.data.indentLevel)\r\n\r\n // this.wrapper.addEventListener(\"keypress\", this.handlePropagationForKeyEvent.bind(this), { capture: true })\r\n // this.wrapper.addEventListener(\"keyup\", this.handlePropagationForKeyEvent.bind(this), { capture: true })\r\n this.wrapper.addEventListener('keydown', (...args) => this.onKeyDown.apply(this, args), { capture: true })\r\n this.wrapper.addEventListener(\"focus\", (e) => this.onFocus.call(this, e), { capture: true });\r\n this.wrapper.addEventListener(\"blur\", (e) => this.onBlur.call(this, e), { capture: true });\r\n\r\n return this.wrapper\r\n }\r\n\r\n public save() {\r\n return this.data\r\n }\r\n\r\n private get CSS() {\r\n return {\r\n customPopoverItem: 'ce-popover-indent-item',\r\n popoverItem: 'ce-popover-item',\r\n popoverItemIcon: 'ce-popover-item__icon',\r\n popoverItemTitle: 'ce-popover-item__title',\r\n disabledItem: 'ce-popover-item--disabled',\r\n highlightIndent: \"ce-highlight-indent\",\r\n }\r\n }\r\n private get EditorCSS() {\r\n return {\r\n block: \"ce-block\",\r\n content: \"ce-block__content\",\r\n redactor: \"codex-editor__redactor\",\r\n }\r\n }\r\n\r\n private get TuneNames() {\r\n return {\r\n indentLeft: 'tune-indent-left',\r\n indentRight: 'tune-indent-right',\r\n }\r\n }\r\n\r\n private get customInterval() {\r\n return this.config.customBlockIndentLimits[this.block?.name ?? ''] ?? {}\r\n }\r\n\r\n private get maxIndent() {\r\n return this.customInterval.max ?? this.config.maxIndent\r\n }\r\n\r\n private get minIndent() {\r\n return this.customInterval.min ?? this.config.minIndent\r\n }\r\n\r\n private get isDirectionInverted() {\r\n return this.config.direction !== 'ltr'; // also ignore invalid directions\r\n }\r\n\r\n private get rightText() {\r\n return this.api.i18n.t(this.isDirectionInverted ? 'Un Indent' : 'Indent')\r\n }\r\n\r\n private get leftText() {\r\n return this.api.i18n.t(this.isDirectionInverted ? 'Indent' : 'Un Indent')\r\n }\r\n\r\n private get shouldApplyAutoIndent(): boolean {\r\n if (!this.config.autoIndent) return false\r\n if (typeof this.config.autoIndent === 'boolean') return this.config.autoIndent;\r\n\r\n // the index is still on the previous block\r\n const previousBlockIndex = this.api.blocks.getCurrentBlockIndex()\r\n // const previousBlockIndex = currentBlockIndex// - 1;\r\n if (previousBlockIndex < 0) return false;\r\n\r\n const previousBlock = this.api.blocks.getBlockByIndex(previousBlockIndex)\r\n if (!previousBlock) return false;\r\n\r\n const previousBlockName = previousBlock.name;\r\n return !this.config.autoIndent.tuneNames?.length || this.config.autoIndent.tuneNames.includes(previousBlockName)\r\n }\r\n\r\n private handlePropagationForKeyEvent(e: KeyboardEvent): { isIndent: boolean } | null {\r\n if (!this.block?.id) return null;\r\n // omit key shortcut entirely\r\n if (this.config.handleShortcut === false) return null;\r\n\r\n const isDefaultKeyPressed = e.key == this.DEFAULT_INDENT_KEY\r\n const isCustomBehaviourDefined = typeof this.config.handleShortcut === 'function'\r\n\r\n if (!isCustomBehaviourDefined && !isDefaultKeyPressed) return null\r\n\r\n const handledCommand = this.config.handleShortcut?.(e, this.block.id)\r\n const shouldIgnoreKeyPress = !handledCommand && isCustomBehaviourDefined\r\n if (shouldIgnoreKeyPress) return null\r\n\r\n let isIndent: boolean;\r\n switch (handledCommand) {\r\n case 'indent':\r\n isIndent = true;\r\n break\r\n case 'unindent':\r\n isIndent = false;\r\n break;\r\n case 'default':\r\n default:\r\n if (!isDefaultKeyPressed) return null;\r\n isIndent = !e.shiftKey\r\n }\r\n\r\n e.stopPropagation()\r\n e.preventDefault()\r\n\r\n return { isIndent }\r\n }\r\n\r\n private onKeyDown(e: KeyboardEvent) {\r\n if (!this.block?.id) return;\r\n\r\n const handlingResult = this.handlePropagationForKeyEvent(e)\r\n if (!handlingResult) return;\r\n const { isIndent } = handlingResult\r\n\r\n //this might be still open\r\n this.api.inlineToolbar.close()\r\n const selectedBlocks = this.getGlobalSelectedBlocks()\r\n const isSingleLineBlock = !this.config.multiblock || selectedBlocks.length < 2\r\n if (isSingleLineBlock) {\r\n if (isIndent) this.indentBlock()\r\n else this.unIndentBlock()\r\n this.block.dispatchChange?.()\r\n return\r\n }\r\n\r\n if (!Boolean(this.config.tuneName)) {\r\n console.error(`'tuneName' is empty.`)\r\n return\r\n }\r\n\r\n selectedBlocks.forEach(async (b) => {\r\n //get block indent level\r\n const savedData = await b.save()\r\n if (!savedData) return\r\n\r\n if (!('tunes' in savedData) || typeof savedData.tunes !== 'object' || !savedData.tunes) {\r\n console.error('Multiblock indenting is not supported for this editor version. ')\r\n return\r\n }\r\n\r\n //this somehow SAVES fine\r\n const tune = (savedData.tunes as Record<string, IndentData>)[this.config.tuneName ?? ''] as IndentData | undefined\r\n if (!tune) {\r\n console.error(`'tuneName' is invalid, no tune was found for block ${b.name}`)\r\n return\r\n }\r\n if (isIndent) tune.indentLevel = Math.min(this.config.maxIndent, (tune.indentLevel ?? 0) + 1)\r\n else tune.indentLevel = Math.max(0, (tune.indentLevel ?? 0) - 1)\r\n b.dispatchChange?.()\r\n\r\n //apply visual feedback manually, since we can't make the tune update on other blocks\r\n const blockWrapper = this.getWrapperBlockById(b.id)\r\n if (blockWrapper instanceof HTMLElement) {\r\n this.applyStylesToWrapper(blockWrapper, tune.indentLevel)\r\n }\r\n })\r\n }\r\n\r\n private handleIndentLeft() {\r\n if (this.isDirectionInverted)\r\n this.indentBlock();\r\n else\r\n this.unIndentBlock();\r\n this.block?.dispatchChange?.()\r\n }\r\n\r\n private handleIndentRight() {\r\n if (this.isDirectionInverted)\r\n this.unIndentBlock();\r\n else\r\n this.indentBlock();\r\n this.block?.dispatchChange?.()\r\n }\r\n\r\n private indentBlock() {\r\n if (!this.wrapper) return\r\n this.data.indentLevel = Math.min(this.data.indentLevel + 1, this.maxIndent)\r\n\r\n this.applyStylesToWrapper(this.wrapper, this.data.indentLevel)\r\n\r\n this.toggleDisableStateForButtons()\r\n }\r\n\r\n private unIndentBlock() {\r\n if (!this.wrapper) return\r\n this.data.indentLevel = Math.max(this.data.indentLevel - 1, this.minIndent)\r\n\r\n this.applyStylesToWrapper(this.wrapper, this.data.indentLevel)\r\n\r\n this.toggleDisableStateForButtons()\r\n }\r\n\r\n private autoIndentBlock() {\r\n const currentBlockIndex = this.api.blocks.getBlockIndex(this.block!.id)\r\n const previousBlock = this.api.blocks.getBlockByIndex(currentBlockIndex - 1)\r\n\r\n if (!previousBlock) return\r\n\r\n const previousBlockIndentLevelAttribute = previousBlock.holder?.querySelector(`[${IndentTune.DATA_WRAPPER_NAME}]`)\r\n ?.getAttribute(IndentTune.DATA_INDENT_LEVEL);\r\n\r\n const previousBlockIndentLevel = Number(\r\n previousBlockIndentLevelAttribute ?? 0,\r\n )\r\n\r\n const currentBlockIndentLevel = Math.min(Math.max(previousBlockIndentLevel, this.minIndent), this.maxIndent)\r\n\r\n this.data.indentLevel = currentBlockIndentLevel\r\n\r\n this.applyStylesToWrapper(this.wrapper, this.data.indentLevel)\r\n }\r\n\r\n private toggleDisableStateForButtons() {\r\n if (this.data.indentLevel === this.minIndent)\r\n this.getTuneButton('unindent')?.classList.add(this.CSS.disabledItem)\r\n else\r\n this.getTuneButton('unindent')?.classList.remove(this.CSS.disabledItem)\r\n\r\n if (this.data.indentLevel === this.maxIndent)\r\n this.getTuneButton('indent')?.classList.add(this.CSS.disabledItem)\r\n else\r\n this.getTuneButton('indent')?.classList.remove(this.CSS.disabledItem)\r\n }\r\n\r\n private getTuneButton(indentType: 'indent' | 'unindent') {\r\n let indentName: 'indentLeft' | \"indentRight\" = indentType === 'indent' ? \"indentRight\" : \"indentLeft\";\r\n if (this.isDirectionInverted)\r\n indentName = indentType == 'indent' ? \"indentLeft\" : \"indentRight\";\r\n\r\n return this.config.orientation === 'vertical'\r\n ? this.getTuneByName(`${this.TuneNames[indentName]}-${this.block?.id}`)\r\n : document.querySelector(`.${this.CSS.popoverItemIcon}[data-${this.TuneNames[indentName]}]`)\r\n }\r\n\r\n private getTuneByName(name: string) {\r\n return document.querySelector(`.${this.CSS.popoverItem}[data-item-name=\"${name}\"]`)\r\n }\r\n\r\n private getTuneTitleByName(name: string) {\r\n return this.getTuneByName(name)?.querySelector(`.${this.CSS.popoverItemTitle}`)\r\n }\r\n\r\n private applyStylesToWrapper(givenWrapper: HTMLElement, indentLevel: number = parseInt(givenWrapper.getAttribute(IndentTune.DATA_INDENT_LEVEL) || \"0\")) {\r\n const indentValue = indentLevel * this.config.indentSize;\r\n givenWrapper.setAttribute(IndentTune.DATA_INDENT_LEVEL, indentLevel.toString());\r\n\r\n const contentElement = givenWrapper.querySelector(`.${this.EditorCSS.content}`);\r\n const blockElement = this.getBlockForWrapper(givenWrapper) || document.querySelector(`.${this.EditorCSS.redactor}`);\r\n if (!(contentElement instanceof HTMLElement) || !blockElement) return;\r\n\r\n const blockWidth = blockElement.getBoundingClientRect().width;\r\n if (blockWidth === 0) //block is not in DOM yet/redactor is hidden, depends on editorjs version\r\n {\r\n queueMicrotask(() => this.applyStylesToWrapper.bind(this)(givenWrapper, indentLevel))\r\n return\r\n }\r\n const normalContentWidth = this.maxWidthForContent(givenWrapper);\r\n\r\n // until margin inline == 0;\r\n const maxApplyableIndent = (blockWidth - normalContentWidth) / 2\r\n\r\n const indentToApply = Math.max(0, Math.min(maxApplyableIndent, indentValue));\r\n //have to double the value because content inside has margin inline;\r\n const indentValuePixels = `${indentToApply * 2}px`;\r\n const indentValuePixelsForHighlight = `${indentToApply}px`;\r\n\r\n // because the direction has been changed\r\n // const omitTransitionTemporarily = givenWrapper.style[this.isDirectionInverted ? 'paddingLeft' : \"paddingRight\"] === \"0px\"\r\n // if (omitTransitionTemporarily) this.omitTransitionTemporarily(givenWrapper)\r\n\r\n if (this.isDirectionInverted) {\r\n givenWrapper.style.paddingLeft = '0px';\r\n givenWrapper.style.paddingRight = indentValuePixels;\r\n } else {\r\n givenWrapper.style.paddingLeft = indentValuePixels;\r\n givenWrapper.style.paddingRight = \"0px\";\r\n }\r\n\r\n const highlightElement = givenWrapper.querySelector(`.${this.CSS.highlightIndent}`)\r\n if (!(highlightElement instanceof HTMLElement)) return;\r\n\r\n // if (omitTransitionTemporarily) this.omitTransitionTemporarily(highlightElement)\r\n\r\n if (this.isDirectionInverted) {\r\n highlightElement.style.width = indentValuePixelsForHighlight;\r\n highlightElement.style.left = \"100%\";\r\n highlightElement.style.right = '';\r\n }\r\n else {\r\n highlightElement.style.width = indentValuePixelsForHighlight;\r\n highlightElement.style.left = \"\";\r\n highlightElement.style.right = '100%';\r\n }\r\n }\r\n\r\n private onFocus(e: FocusEvent) {\r\n if (!(e.target instanceof HTMLElement)) return;\r\n const isInsideCurrentBlock = this.wrapper.contains(e.target);\r\n if (!isInsideCurrentBlock) return;\r\n this.wrapper.setAttribute(IndentTune.DATA_FOCUSED, '');\r\n }\r\n\r\n private onBlur(e: FocusEvent) {\r\n if (!(e.target instanceof HTMLElement)) return;\r\n const isInsideCurrentBlock = this.wrapper.contains(e.target);\r\n if (!isInsideCurrentBlock) return;\r\n this.wrapper.removeAttribute(IndentTune.DATA_FOCUSED);\r\n }\r\n\r\n private lastResizeTimeout: null | NodeJS.Timeout = null;\r\n private onResize(e: UIEvent) {\r\n const timeoutDelayMs = 500;\r\n if (this.lastResizeTimeout)\r\n clearTimeout(this.lastResizeTimeout)\r\n this.lastResizeTimeout = setTimeout(() => {\r\n const allWrappers = document.querySelectorAll(`[${IndentTune.DATA_WRAPPER_NAME}]`);\r\n allWrappers.forEach((w) => {\r\n if (!(w instanceof HTMLElement)) return;\r\n this.applyStylesToWrapper(w);\r\n });\r\n }, timeoutDelayMs);\r\n }\r\n\r\n private getGlobalSelectedBlocks() {\r\n const crossSelectedBlocks = new Array(this.api.blocks.getBlocksCount())\r\n .fill(0)\r\n .map((_, idx) => this.api.blocks.getBlockByIndex(idx))\r\n .filter((b): b is BlockAPI => !!b?.selected)\r\n return crossSelectedBlocks\r\n }\r\n\r\n private getWrapperBlockById(blockId: string) {\r\n const selector = `.${this.EditorCSS.block}[data-id=\"${blockId}\"] [${IndentTune.DATA_WRAPPER_NAME}]`\r\n return document.querySelector(selector) ??\r\n this.api.blocks.getById(blockId)?.holder.querySelector(`[${IndentTune.DATA_WRAPPER_NAME}]`)\r\n ?? null;\r\n }\r\n\r\n private getBlockForWrapper(wrapper: HTMLElement): HTMLElement | null {\r\n let current = wrapper;\r\n while ((!current.classList.contains(this.EditorCSS.block))) {\r\n if (!current.parentElement || (current instanceof HTMLHtmlElement)) return null;\r\n current = current.parentElement;\r\n }\r\n\r\n return current\r\n }\r\n\r\n private alignmentChangeListener(blockId: string, direction: TextDirection) {\r\n // across all blocks this function is called, so we got to filter out\r\n if (blockId !== this.block?.id) return;\r\n const hasDirectionChanged = direction !== this.config.direction\r\n if (!hasDirectionChanged) return\r\n\r\n this.config.direction = direction;\r\n this.applyStylesToWrapper(this.wrapper, this.data.indentLevel)\r\n this.toggleDisableStateForButtons()\r\n if (this.config.orientation === 'vertical') {\r\n // I have to update the text for the indent options 😪\r\n\r\n const indentRightBtnTitle = this.getTuneTitleByName(`${this.TuneNames.indentRight}-${this.block?.id}`);\r\n if (indentRightBtnTitle) indentRightBtnTitle.textContent = this.rightText\r\n\r\n const indentLeftBtnTitle = this.getTuneTitleByName(`${this.TuneNames.indentLeft}-${this.block?.id}`);\r\n if (indentLeftBtnTitle) indentLeftBtnTitle.textContent = this.leftText\r\n }\r\n }\r\n\r\n private createElementFromTemplate(template: string): HTMLElement {\r\n return new DOMParser().parseFromString(template, 'text/html').body.firstChild as HTMLElement;\r\n }\r\n\r\n // private omitTransitionTemporarily(element: HTMLElement) {\r\n // element.style.transitionDuration = \"0s\";\r\n // (() => {\r\n // element.style.transitionDuration = \"\";\r\n // })\r\n // }\r\n\r\n private changeConfigBasedOnVersionIfNeeded() {\r\n if (!this.config.version) return;\r\n\r\n if (this.config.version < '2.27' && this.config.orientation === 'vertical') {\r\n this.config.orientation = 'horizontal';\r\n\r\n if (!warnings.orientation)\r\n console.warn(\"Current editor version does not support vertical indent tune 'orientation'. View your config input\")\r\n warnings.orientation = true;\r\n }\r\n }\r\n\r\n private cachedMaxWidthForContent: number | null = null;\r\n private maxWidthForContent(elementInsideEditor: HTMLElement): number {\r\n const content = elementInsideEditor.querySelector(`.${this.EditorCSS.content}`);\r\n if ((content instanceof HTMLElement)) {\r\n const { maxWidth } = window.getComputedStyle(content);\r\n if (maxWidth) {\r\n this.cachedMaxWidthForContent = parseInt(maxWidth);\r\n return this.cachedMaxWidthForContent\r\n }\r\n }\r\n\r\n if (this.cachedMaxWidthForContent !== null) return this.cachedMaxWidthForContent\r\n // Get value from stylesheet\r\n // for (let i = 0; i < document.styleSheets.length; i++) {\r\n // const styleSheet = document.styleSheets.item(i);\r\n // if (!styleSheet || !(styleSheet.ownerNode instanceof HTMLStyleElement) || styleSheet.ownerNode.id !== \"editor-js-styles\") continue;\r\n\r\n // for (let j = 0; j < styleSheet.cssRules.length; j++) {\r\n // const rule = styleSheet.cssRules.item(j);\r\n // if (!rule) continue;\r\n // const selector = `.${this.EditorCSS.content}`\r\n // if (!rule.cssText.startsWith(selector + \" {\") && (rule as { selectorText?: string }).selectorText !== selector)\r\n // continue;\r\n // const matches = /max-width: [\\d]+px;/.exec(rule.cssText)\r\n // if (!matches || !matches.length) continue;\r\n\r\n // const maxWidth = parseInt(matches[0].replace(\"max-width:\", ''));\r\n // this.cachedMaxWidthForContent = maxWidth;\r\n // return this.maxWidthForContent;\r\n // }\r\n\r\n // }\r\n // console.warn(\"Cannot detect EditorJs max width for content. Please contact package author\")\r\n this.cachedMaxWidthForContent = 650;\r\n return this.cachedMaxWidthForContent;\r\n }\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\nimport type { API } from '@ebl-vue/editorjs';\r\nimport { IconMarker } from '../../icons';\r\n\r\n/**\r\n * Marker Tool for the Editor.js\r\n *\r\n * Allows to wrap inline fragment and style it somehow.\r\n */\r\nexport default class Marker {\r\n private api: API;\r\n private button: HTMLElement | null;\r\n private tag: string;\r\n private iconClasses: {base: string; active: string};\r\n\r\n static get toolboxIcon() {\r\n return IconMarker;\r\n }\r\n /**\r\n * Class name for term-tag\r\n *\r\n * @type {string}\r\n */\r\n static get CSS() {\r\n return 'cdx-marker';\r\n };\r\n\r\n /**\r\n * @param {{api: object}} - Editor.js API\r\n */\r\n constructor({api}: {api: any}) {\r\n this.api = api;\r\n\r\n /**\r\n * Toolbar Button\r\n *\r\n * @type {HTMLElement|null}\r\n */\r\n this.button = null;\r\n\r\n /**\r\n * Tag represented the term\r\n *\r\n * @type {string}\r\n */\r\n this.tag = 'MARK';\r\n\r\n /**\r\n * CSS classes\r\n */\r\n this.iconClasses = {\r\n base: this.api.styles.inlineToolButton,\r\n active: this.api.styles.inlineToolButtonActive\r\n };\r\n }\r\n\r\n /**\r\n * Specifies Tool as Inline Toolbar Tool\r\n *\r\n * @return {boolean}\r\n */\r\n static get isInline() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Create button element for Toolbar\r\n *\r\n * @return {HTMLElement}\r\n */\r\n render() {\r\n this.button = document.createElement('button');\r\n //this.button.type = 'button';\r\n this.button.setAttribute(\"type\", \"button\");\r\n this.button.classList.add(this.iconClasses.base);\r\n this.button.innerHTML = this.toolboxIcon;\r\n\r\n return this.button;\r\n }\r\n\r\n /**\r\n * Wrap/Unwrap selected fragment\r\n *\r\n * @param {Range} range - selected fragment\r\n */\r\n surround(range:Range) {\r\n if (!range) {\r\n return;\r\n }\r\n\r\n let termWrapper = this.api.selection.findParentTag(this.tag, Marker.CSS);\r\n\r\n /**\r\n * If start or end of selection is in the highlighted block\r\n */\r\n if (termWrapper) {\r\n this.unwrap(termWrapper);\r\n } else {\r\n this.wrap(range);\r\n }\r\n }\r\n\r\n /**\r\n * Wrap selection with term-tag\r\n *\r\n * @param {Range} range - selected fragment\r\n */\r\n wrap(range:Range) {\r\n /**\r\n * Create a wrapper for highlighting\r\n */\r\n let marker = document.createElement(this.tag);\r\n\r\n marker.classList.add(Marker.CSS);\r\n\r\n /**\r\n * SurroundContent throws an error if the Range splits a non-Text node with only one of its boundary points\r\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Range/surroundContents}\r\n *\r\n * // range.surroundContents(span);\r\n */\r\n marker.appendChild(range.extractContents());\r\n range.insertNode(marker);\r\n\r\n /**\r\n * Expand (add) selection to highlighted block\r\n */\r\n this.api.selection.expandToTag(marker);\r\n }\r\n\r\n /**\r\n * Unwrap term-tag\r\n *\r\n * @param {HTMLElement} termWrapper - term wrapper tag\r\n */\r\n unwrap(termWrapper: HTMLElement) {\r\n /**\r\n * Expand selection to all term-tag\r\n */\r\n this.api.selection.expandToTag(termWrapper);\r\n\r\n let sel = window.getSelection();\r\n let range = sel?.getRangeAt(0);\r\n\r\n let unwrappedContent = range?.extractContents();\r\n\r\n /**\r\n * Remove empty term-tag\r\n */\r\n termWrapper?.parentNode?.removeChild(termWrapper);\r\n\r\n /**\r\n * Insert extracted content\r\n */\r\n if (unwrappedContent) {\r\n range?.insertNode(unwrappedContent);\r\n }\r\n /**\r\n * Restore selection\r\n */\r\n sel?.removeAllRanges();\r\n if (range) {\r\n sel?.addRange(range);\r\n }\r\n }\r\n\r\n /**\r\n * Check and change Term's state for current selection\r\n */\r\n checkState() {\r\n const termTag = this.api.selection.findParentTag(this.tag, Marker.CSS);\r\n\r\n this.button?.classList.toggle(this.iconClasses.active, !!termTag);\r\n }\r\n\r\n /**\r\n * Get Tool icon's SVG\r\n * @return {string}\r\n */\r\n get toolboxIcon() {\r\n return IconMarker;\r\n }\r\n\r\n /**\r\n * Sanitizer rule\r\n * @return {{mark: {class: string}}}\r\n */\r\n static get sanitize() {\r\n return {\r\n mark: {\r\n class: Marker.CSS\r\n }\r\n };\r\n }\r\n}\r\n\r\n","import { API } from '@ebl-vue/editorjs';\r\nimport { IconColor } from \"../../icons\";\r\n\r\n\r\nimport './styles.css';\r\n\r\nimport {type InlineToolConstructorOptions} from \"@ebl-vue/editorjs/types/tools/inline-tool\";\r\n\r\n\r\n\r\nexport default class ColorPicker {\r\n\tprivate api: API;\r\n\r\n\ttag = 'SPAN';\r\n\tclass = 'cdx-text-color';\r\n\tdefaultColor = '#2644FF';\r\n\r\n\tlastRange: Range | null = null;\r\n\r\n\tcolors: string[] = [\r\n\t\t'#182a4e',\r\n\t\t'#0055cc',\r\n\t\t'#1f6a83',\r\n\t\t'#206e4e',\r\n\t\t'#e56910',\r\n\t\t'#ae2e24',\r\n\t\t'#5e4db2',\r\n\t\t'#758195',\r\n\t\t'#1e7afd',\r\n\t\t'#2998bd',\r\n\t\t'#23a06b',\r\n\t\t'#fea363',\r\n\t\t'#c9372c',\r\n\t\t'#8270db',\r\n\t];\r\n\tcolumns = 7;\r\n\r\n\tstatic get title() {\r\n\t\treturn 'Color';\r\n\t}\r\n\r\n\tstatic get isInline() {\r\n\t\treturn true;\r\n\t}\r\n\r\n\tconstructor(args:InlineToolConstructorOptions) {\r\n\t\tconst { api, config } = args;\r\n\t\tthis.api = api;\r\n\r\n\t\tif (config.colors) {\r\n\t\t\tthis.colors = config.colors;\r\n\t\t}\r\n\t\tif (config.columns) {\r\n\t\t\tthis.columns = config.columns;\r\n\t\t}\r\n\t}\r\n\r\n\trender() {\r\n\t\tconst button = document.createElement('button');\r\n\r\n\t\tbutton.type = 'button';\r\n\t\tbutton.innerHTML = IconColor;\r\n\t\tbutton.classList.add(this.api.styles.inlineToolButton);\r\n\r\n\t\tbutton.addEventListener('mousedown', (e) => {\r\n\t\t\t// prevent text deselection when clicking the button\r\n\t\t\te.preventDefault();\r\n\t\t});\r\n\r\n\t\treturn button;\r\n\t}\r\n\r\n\tsurround(range: Range | null) {\r\n\t\tthis.lastRange = range;\r\n\t}\r\n\r\n\twrapAndColor(range: Range | null, color: string) {\r\n\t\tif (!range) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst selectedText = range.extractContents();\r\n\t\tconst span = document.createElement(this.tag);\r\n\t\tspan.classList.add(this.class);\r\n\t\tspan.appendChild(selectedText);\r\n\t\tspan.style.color = color;\r\n\t\tspan.innerHTML = span.textContent || '';\r\n\t\trange.insertNode(span);\r\n\r\n\t\tthis.api.selection.expandToTag(span);\r\n\t}\r\n\r\n\trenderActions() {\r\n\t\tconst container = document.createElement('div');\r\n\t\tcontainer.classList.add('editorjs__color-selector-container');\r\n\t\tcontainer.style.gridTemplateColumns = `repeat(${this.columns}, 1fr)`;\r\n\r\n\t\tthis.colors.forEach((colorValue) => {\r\n\t\t\tconst color = document.createElement('div');\r\n\t\t\tcolor.classList.add('editorjs__color-selector__container-item');\r\n\t\t\tcolor.style.backgroundColor = colorValue;\r\n\t\t\tcolor.onclick = () => {\r\n\t\t\t\tthis.wrapAndColor(this.lastRange, colorValue);\r\n\t\t\t};\r\n\t\t\tcontainer.append(color);\r\n\t\t});\r\n\r\n\t\treturn container;\r\n\t}\r\n\r\n\t/**\r\n\t * Sanitizer rules\r\n\t *\r\n\t * @returns {object}\r\n\t */\r\n\tstatic get sanitize(): any {\r\n\t\treturn {\r\n\t\t\tspan: {\r\n\t\t\t\tstyle: {\r\n\t\t\t\t\tcolor: true,\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t};\r\n\t}\r\n}\r\n\r\nexport class ColorPickerWithoutSanitize extends ColorPicker {\r\n\tstatic override get sanitize() {\r\n\t\treturn undefined;\r\n\t}\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\nimport { IconUnderline } from '../../icons';\r\n\r\nimport {type API, type InlineTool, type SanitizerConfig} from \"@ebl-vue/editorjs\";\r\nimport {type InlineToolConstructorOptions} from \"@ebl-vue/editorjs/types/tools/inline-tool\";\r\n\r\n/**\r\n * Underline Tool for the Editor.js\r\n *\r\n * Allows to wrap inline fragment and style it somehow.\r\n */\r\nexport default class Underline implements InlineTool {\r\n /**\r\n * Class name for term-tag\r\n *\r\n * @type {string}\r\n */\r\n static get CSS(): string {\r\n return 'cdx-underline';\r\n };\r\n\r\n /**\r\n * Toolbar Button\r\n *\r\n * @type {HTMLButtonElement}\r\n */\r\n private button: HTMLButtonElement | undefined\r\n\r\n /**\r\n * Tag represented the term\r\n *\r\n * @type {string}\r\n */\r\n private tag: string = 'U';\r\n\r\n /**\r\n * API InlineToolConstructorOptions\r\n *\r\n * @type {API}\r\n */\r\n private api: API\r\n\r\n /**\r\n * CSS classes\r\n *\r\n * @type {object}\r\n */\r\n private iconClasses: {base: string, active: string}\r\n\r\n /**\r\n * @param options InlineToolConstructorOptions\r\n */\r\n public constructor(options: InlineToolConstructorOptions) {\r\n this.api = options.api;\r\n\r\n /**\r\n * CSS classes\r\n */\r\n this.iconClasses = {\r\n base: this.api.styles.inlineToolButton,\r\n active: this.api.styles.inlineToolButtonActive,\r\n };\r\n }\r\n\r\n /**\r\n * Specifies Tool as Inline Toolbar Tool\r\n *\r\n * @returns {boolean}\r\n */\r\n public static isInline = true;\r\n\r\n /**\r\n * Create button element for Toolbar\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n public render(): HTMLElement {\r\n this.button = document.createElement('button');\r\n this.button.type = 'button';\r\n this.button.classList.add(this.iconClasses.base);\r\n this.button.innerHTML = this.toolboxIcon;\r\n\r\n return this.button;\r\n }\r\n\r\n /**\r\n * Wrap/Unwrap selected fragment\r\n *\r\n * @param {Range} range - selected fragment\r\n */\r\n public surround(range: Range): void {\r\n if (!range) {\r\n return;\r\n }\r\n\r\n const termWrapper = this.api.selection.findParentTag(this.tag, Underline.CSS);\r\n\r\n /**\r\n * If start or end of selection is in the highlighted block\r\n */\r\n if (termWrapper) {\r\n this.unwrap(termWrapper);\r\n } else {\r\n this.wrap(range);\r\n }\r\n }\r\n\r\n /**\r\n * Wrap selection with term-tag\r\n *\r\n * @param {Range} range - selected fragment\r\n */\r\n public wrap(range: Range) {\r\n /**\r\n * Create a wrapper for highlighting\r\n */\r\n const u = document.createElement(this.tag);\r\n\r\n u.classList.add(Underline.CSS);\r\n\r\n /**\r\n * SurroundContent throws an error if the Range splits a non-Text node with only one of its boundary points\r\n *\r\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Range/surroundContents}\r\n *\r\n * // range.surroundContents(span);\r\n */\r\n u.appendChild(range.extractContents());\r\n range.insertNode(u);\r\n\r\n /**\r\n * Expand (add) selection to highlighted block\r\n */\r\n this.api.selection.expandToTag(u);\r\n }\r\n\r\n /**\r\n * Unwrap term-tag\r\n *\r\n * @param {HTMLElement} termWrapper - term wrapper tag\r\n */\r\n public unwrap(termWrapper: HTMLElement): void {\r\n /**\r\n * Expand selection to all term-tag\r\n */\r\n this.api.selection.expandToTag(termWrapper);\r\n\r\n const sel = window.getSelection();\r\n if (!sel) {\r\n return;\r\n }\r\n const range = sel.getRangeAt(0);\r\n if (!range) {\r\n return\r\n }\r\n\r\n const unwrappedContent = range.extractContents();\r\n if (!unwrappedContent) {\r\n return\r\n }\r\n\r\n /**\r\n * Remove empty term-tag\r\n */\r\n termWrapper.parentNode?.removeChild(termWrapper);\r\n\r\n /**\r\n * Insert extracted content\r\n */\r\n range.insertNode(unwrappedContent);\r\n\r\n /**\r\n * Restore selection\r\n */\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n }\r\n\r\n /**\r\n * Check and change Term's state for current selection\r\n */\r\n public checkState(): boolean {\r\n const termTag = this.api.selection.findParentTag(this.tag, Underline.CSS);\r\n\r\n this.button?.classList.toggle(this.iconClasses.active, !!termTag);\r\n\r\n return !!termTag\r\n }\r\n\r\n /**\r\n * Get Tool icon's SVG\r\n *\r\n * @returns {string}\r\n */\r\n public get toolboxIcon(): string {\r\n return IconUnderline;\r\n }\r\n\r\n /**\r\n * Sanitizer rule\r\n *\r\n * @returns {{u: {class: string}}}\r\n */\r\n public static get sanitize(): SanitizerConfig {\r\n return {\r\n u: {\r\n class: Underline.CSS,\r\n },\r\n };\r\n }\r\n}\r\n","/**\r\n * Build styles\r\n */\r\nimport './index.css';\r\nimport {IconBrackets} from '../../icons';\r\n\r\nimport { API, InlineTool, InlineToolConstructorOptions, SanitizerConfig } from \"@editorjs/editorjs\";\r\n\r\ninterface IconClasses {\r\n base: string;\r\n active: string;\r\n}\r\n\r\n/**\r\n * Inline Code Tool for the Editor.js\r\n *\r\n * Allows to wrap inline fragment and style it somehow.\r\n */\r\nexport default class InlineCode implements InlineTool {\r\n /**\r\n * Editor.js API\r\n */\r\n private api: API;\r\n /**\r\n * Button element for the toolbar\r\n */\r\n private button: HTMLButtonElement | null;\r\n /**\r\n * Tag representing the term\r\n */\r\n private tag: string = 'CODE';\r\n /**\r\n * CSS classes for the icon\r\n */\r\n private iconClasses: IconClasses;\r\n\r\n /**\r\n * Class name for term-tag\r\n *\r\n * @type {string}\r\n */\r\n static get CSS(): string {\r\n return 'inline-code';\r\n }\r\n\r\n constructor({ api }: InlineToolConstructorOptions) {\r\n this.api = api;\r\n\r\n this.button = null;\r\n\r\n this.iconClasses = {\r\n base: this.api.styles.inlineToolButton,\r\n active: this.api.styles.inlineToolButtonActive,\r\n };\r\n }\r\n\r\n /**\r\n * Specifies Tool as Inline Toolbar Tool\r\n *\r\n * @return {boolean}\r\n */\r\n static get isInline(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Create button element for Toolbar\r\n *\r\n * @return {HTMLElement}\r\n */\r\n render(): HTMLElement {\r\n this.button = document.createElement('button');\r\n this.button.type = 'button';\r\n this.button.classList.add(this.iconClasses.base);\r\n this.button.innerHTML = this.toolboxIcon;\r\n\r\n return this.button;\r\n }\r\n\r\n /**\r\n * Wrap/Unwrap selected fragment\r\n *\r\n * @param {Range} range - selected fragment\r\n */\r\n surround(range: Range): void {\r\n if (!range) {\r\n return;\r\n }\r\n\r\n let termWrapper = this.api.selection.findParentTag(this.tag, InlineCode.CSS) as HTMLElement;\r\n\r\n /**\r\n * If the start or end of the selection range is within a highlighted block\r\n */\r\n if (termWrapper) {\r\n this.unwrap(termWrapper);\r\n } else {\r\n const existingCodeTag = range.commonAncestorContainer.parentElement?.querySelector(this.tag);\r\n if (!existingCodeTag) {\r\n this.wrap(range);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Wrap selection with term-tag\r\n *\r\n * @param {Range} range - selected fragment\r\n */\r\n wrap(range: Range): void {\r\n /**\r\n * Create a wrapper for highlighting\r\n */\r\n let span = document.createElement(this.tag);\r\n\r\n span.classList.add(InlineCode.CSS);\r\n\r\n /**\r\n * SurroundContent throws an error if the Range splits a non-Text node with only one of its boundary points\r\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Range/surroundContents}\r\n *\r\n * // range.surroundContents(span);\r\n */\r\n span.appendChild(range.extractContents());\r\n range.insertNode(span);\r\n\r\n /**\r\n * Expand (add) selection to highlighted block\r\n */\r\n this.api.selection.expandToTag(span);\r\n }\r\n\r\n /**\r\n * Unwrap term-tag\r\n *\r\n * @param {HTMLElement} termWrapper - term wrapper tag\r\n */\r\n unwrap(termWrapper: HTMLElement): void {\r\n /**\r\n * Expand selection to all term-tag\r\n */\r\n this.api.selection.expandToTag(termWrapper);\r\n\r\n const sel = window.getSelection();\r\n if (!sel) return;\r\n\r\n const range = sel.getRangeAt(0);\r\n const unwrappedContent = range.extractContents();\r\n\r\n /**\r\n * Remove empty term-tag\r\n */\r\n termWrapper.parentNode?.removeChild(termWrapper);\r\n\r\n /**\r\n * Insert extracted content\r\n */\r\n range.insertNode(unwrappedContent);\r\n\r\n /**\r\n * Restore selection\r\n */\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n }\r\n\r\n /**\r\n * Check and change Term's state for current selection\r\n * \r\n * @return {boolean}\r\n */\r\n checkState(): boolean {\r\n const termTag = this.api.selection.findParentTag(this.tag, InlineCode.CSS);\r\n\r\n if (this.button) {\r\n this.button.classList.toggle(this.iconClasses.active, !!termTag);\r\n }\r\n\r\n return !!termTag;\r\n }\r\n\r\n\r\n /**\r\n * Get Tool icon's SVG\r\n * @return {string}\r\n */\r\n get toolboxIcon(): string {\r\n return IconBrackets;\r\n }\r\n\r\n /**\r\n * Sanitizer rule\r\n * @return {SanitizerConfig}\r\n */\r\n static get sanitize(): SanitizerConfig {\r\n return {\r\n code: {\r\n class: InlineCode.CSS,\r\n },\r\n };\r\n }\r\n}\r\n","/**\r\n * Helper for making Elements with attributes\r\n *\r\n * @param {string} tagName - new Element tag name\r\n * @param {string|string[]} classNames - list or name of CSS classname(s)\r\n * @param {object} attributes - any attributes\r\n * @returns {Element}\r\n */\r\nexport function make(\r\n tagName: string,\r\n classNames: string | string[],\r\n attributes:Record<string, any> = {}\r\n) {\r\n const el = document.createElement(tagName);\r\n\r\n if (Array.isArray(classNames)) {\r\n el.classList.add(...classNames);\r\n } else if (classNames) {\r\n el.classList.add(classNames);\r\n }\r\n\r\n for (const attrName in attributes) {\r\n if (!Object.prototype.hasOwnProperty.call(attributes, attrName)) {\r\n continue;\r\n }\r\n\r\n //el[attrName] = attributes[attrName];\r\n el.setAttribute(attrName, attributes[attrName]);\r\n }\r\n\r\n return el;\r\n}\r\n\r\n/**\r\n * Get item position relative to document\r\n *\r\n * @param {HTMLElement} elem - item\r\n * @returns {{x1: number, y1: number, x2: number, y2: number}} coordinates of the upper left (x1,y1) and lower right(x2,y2) corners\r\n */\r\nexport function getCoords(elem: HTMLElement) {\r\n const rect = elem.getBoundingClientRect();\r\n\r\n return {\r\n y1: Math.floor(rect.top + window.pageYOffset),\r\n x1: Math.floor(rect.left + window.pageXOffset),\r\n x2: Math.floor(rect.right + window.pageXOffset),\r\n y2: Math.floor(rect.bottom + window.pageYOffset)\r\n };\r\n}\r\n\r\n/**\r\n * Calculate paddings of the first element relative to the second\r\n *\r\n * @param {HTMLElement} firstElem - outer element, if the second element is inside it, then all padding will be positive\r\n * @param {HTMLElement} secondElem - inner element, if its borders go beyond the first, then the paddings will be considered negative\r\n * @returns {{fromTopBorder: number, fromLeftBorder: number, fromRightBorder: number, fromBottomBorder: number}}\r\n */\r\nexport function getRelativeCoordsOfTwoElems(firstElem: HTMLElement, secondElem: HTMLElement) {\r\n const firstCoords = getCoords(firstElem);\r\n const secondCoords = getCoords(secondElem);\r\n\r\n return {\r\n fromTopBorder: secondCoords.y1 - firstCoords.y1,\r\n fromLeftBorder: secondCoords.x1 - firstCoords.x1,\r\n fromRightBorder: firstCoords.x2 - secondCoords.x2,\r\n fromBottomBorder: firstCoords.y2 - secondCoords.y2\r\n };\r\n}\r\n\r\n/**\r\n * Get the width and height of an element and the position of the cursor relative to it\r\n *\r\n * @param {HTMLElement} elem - element relative to which the coordinates will be calculated\r\n * @param {Event} event - mouse event\r\n */\r\nexport function getCursorPositionRelativeToElement(elem: HTMLElement, event: MouseEvent) {\r\n const rect = elem.getBoundingClientRect();\r\n const { width, height, x, y } = rect;\r\n const { clientX, clientY } = event;\r\n\r\n return {\r\n width,\r\n height,\r\n x: clientX - x,\r\n y: clientY - y\r\n };\r\n}\r\n\r\n/**\r\n * Insert element after the referenced\r\n *\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} referenceNode\r\n * @returns {HTMLElement}\r\n */\r\nexport function insertAfter(newNode: HTMLElement, referenceNode: HTMLElement) {\r\n return referenceNode?.parentNode?.insertBefore(newNode, referenceNode.nextSibling);\r\n}\r\n\r\n/**\r\n * Insert element after the referenced\r\n *\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} referenceNode\r\n * @returns {HTMLElement}\r\n */\r\nexport function insertBefore(newNode: HTMLElement, referenceNode: HTMLElement) {\r\n return referenceNode?.parentNode?.insertBefore(newNode, referenceNode);\r\n}\r\n\r\n\r\n/**\r\n * Set focus to contenteditable or native input element\r\n *\r\n * @param {Element} element - element where to set focus\r\n * @param {boolean} atStart - where to set focus: at the start or at the end\r\n *\r\n * @returns {void}\r\n */\r\nexport function focus(element: HTMLElement, atStart = true) {\r\n const range = document.createRange();\r\n const selection = window.getSelection();\r\n\r\n range.selectNodeContents(element);\r\n range.collapse(atStart);\r\n\r\n selection?.removeAllRanges();\r\n selection?.addRange(range);\r\n}\r\n","import * as $ from './dom';\r\n\r\n/**\r\n * @typedef {object} PopoverItem\r\n * @property {string} label - button text\r\n * @property {string} icon - button icon\r\n * @property {boolean} confirmationRequired - if true, a confirmation state will be applied on the first click\r\n * @property {function} hideIf - if provided, item will be hid, if this method returns true\r\n * @property {function} onClick - click callback\r\n */\r\ninterface IPopoverItem {\r\n label: string;\r\n icon?: string;\r\n confirmationRequired?: boolean;\r\n hideIf?: () => boolean;\r\n onClick: () => void;\r\n}\r\n/**\r\n * This cass provides a popover rendering\r\n */\r\nexport default class Popover {\r\n private wrapper: HTMLElement|null|undefined;\r\n private items: IPopoverItem[];\r\n private itemEls: HTMLElement[];\r\n /**\r\n * @param {object} options - constructor options\r\n * @param {PopoverItem[]} options.items - constructor options\r\n */\r\n constructor({items}: {items: any}) {\r\n this.items = items;\r\n this.wrapper = undefined;\r\n this.itemEls = [];\r\n }\r\n\r\n /**\r\n * Set of CSS classnames used in popover\r\n *\r\n * @returns {object}\r\n */\r\n static get CSS() {\r\n return {\r\n popover: 'tc-popover',\r\n popoverOpened: 'tc-popover--opened',\r\n item: 'tc-popover__item',\r\n itemHidden: 'tc-popover__item--hidden',\r\n itemConfirmState: 'tc-popover__item--confirm',\r\n itemIcon: 'tc-popover__item-icon',\r\n itemLabel: 'tc-popover__item-label'\r\n };\r\n }\r\n\r\n /**\r\n * Returns the popover element\r\n *\r\n * @returns {Element}\r\n */\r\n render() {\r\n this.wrapper = $.make('div', Popover.CSS.popover);\r\n\r\n this.items.forEach((item:IPopoverItem, index:number) => {\r\n const itemEl = $.make('div', Popover.CSS.item);\r\n const icon = $.make('div', Popover.CSS.itemIcon, {\r\n innerHTML: item.icon\r\n });\r\n const label = $.make('div', Popover.CSS.itemLabel, {\r\n textContent: item.label\r\n });\r\n\r\n itemEl.dataset.index = index + '';\r\n \r\n\r\n itemEl.appendChild(icon);\r\n itemEl.appendChild(label);\r\n\r\n this.wrapper?.appendChild(itemEl);\r\n this.itemEls.push(itemEl);\r\n });\r\n\r\n /**\r\n * Delegate click\r\n */\r\n this.wrapper.addEventListener('click', (event) => {\r\n this.popoverClicked(event);\r\n });\r\n\r\n return this.wrapper;\r\n }\r\n\r\n /**\r\n * Popover wrapper click listener\r\n * Used to delegate clicks in items\r\n *\r\n * @returns {void}\r\n */\r\n popoverClicked(event: MouseEvent) {\r\n const target = event.target as HTMLElement;\r\n const clickedItem = target.closest(`.${Popover.CSS.item}`) as HTMLElement;\r\n\r\n /**\r\n * Clicks outside or between item\r\n */\r\n if (!clickedItem) {\r\n return;\r\n }\r\n\r\n const clickedItemIndex:string|undefined = clickedItem.dataset.index;\r\n if(!clickedItemIndex) return;\r\n\r\n const item = this.items[parseInt(clickedItemIndex)];\r\n\r\n if (item.confirmationRequired && !this.hasConfirmationState(clickedItem)) {\r\n this.setConfirmationState(clickedItem);\r\n\r\n return;\r\n }\r\n\r\n item.onClick();\r\n }\r\n\r\n /**\r\n * Enable the confirmation state on passed item\r\n *\r\n * @returns {void}\r\n */\r\n setConfirmationState(itemEl: HTMLElement) {\r\n itemEl.classList.add(Popover.CSS.itemConfirmState);\r\n }\r\n\r\n /**\r\n * Disable the confirmation state on passed item\r\n *\r\n * @returns {void}\r\n */\r\n clearConfirmationState(itemEl: HTMLElement) {\r\n itemEl.classList.remove(Popover.CSS.itemConfirmState);\r\n }\r\n\r\n /**\r\n * Check if passed item has the confirmation state\r\n *\r\n * @returns {boolean}\r\n */\r\n hasConfirmationState(itemEl: HTMLElement) {\r\n return itemEl.classList.contains(Popover.CSS.itemConfirmState);\r\n }\r\n\r\n /**\r\n * Return an opening state\r\n *\r\n * @returns {boolean}\r\n */\r\n get opened() {\r\n return this.wrapper?.classList.contains(Popover.CSS.popoverOpened) || false;\r\n }\r\n\r\n /**\r\n * Opens the popover\r\n *\r\n * @returns {void}\r\n */\r\n open() {\r\n /**\r\n * If item provides 'hideIf()' method that returns true, hide item\r\n */\r\n this.items.forEach((item, index) => {\r\n if (typeof item.hideIf === 'function') {\r\n this.itemEls[index].classList.toggle(Popover.CSS.itemHidden, item.hideIf());\r\n }\r\n });\r\n\r\n this.wrapper?.classList.add(Popover.CSS.popoverOpened);\r\n }\r\n\r\n /**\r\n * Closes the popover\r\n *\r\n * @returns {void}\r\n */\r\n close() {\r\n this.wrapper?.classList.remove(Popover.CSS.popoverOpened);\r\n this.itemEls.forEach(el => {\r\n this.clearConfirmationState(el);\r\n });\r\n }\r\n}\r\n","import Popover from \"./utils/popover\";\r\nimport * as $ from \"./utils/dom\";\r\nimport { IconMenuSmall } from \"../../icons\";\r\n\r\n/**\r\n * @typedef {object} PopoverItem\r\n * @property {string} label - button text\r\n * @property {string} icon - button icon\r\n * @property {boolean} confirmationRequired - if true, a confirmation state will be applied on the first click\r\n * @property {function} hideIf - if provided, item will be hid, if this method returns true\r\n * @property {function} onClick - click callback\r\n */\r\n\r\n/**\r\n * Toolbox is a menu for manipulation of rows/cols\r\n *\r\n * It contains toggler and Popover:\r\n * <toolbox>\r\n * <toolbox-toggler />\r\n * <popover />\r\n * <toolbox>\r\n */\r\nexport default class Toolbox {\r\n\r\n private items: any;\r\n private onOpen: any;\r\n private onClose: any;\r\n private cssModifier: string;\r\n private popover: Popover | null;\r\n private wrapper: HTMLElement;\r\n /**\r\n * Creates toolbox buttons and toolbox menus\r\n *\r\n * @param {Object} config\r\n * @param {any} config.api - Editor.js api\r\n * @param {PopoverItem[]} config.items - Editor.js api\r\n * @param {function} config.onOpen - callback fired when the Popover is opening\r\n * @param {function} config.onClose - callback fired when the Popover is closing\r\n * @param {string} config.cssModifier - the modifier for the Toolbox. Allows to add some specific styles.\r\n */\r\n constructor({ items, onOpen, onClose, cssModifier = \"\" }: any) {\r\n \r\n\r\n this.items = items;\r\n this.onOpen = onOpen;\r\n this.onClose = onClose;\r\n this.cssModifier = cssModifier;\r\n\r\n this.popover = null;\r\n this.wrapper = this.createToolbox();\r\n }\r\n\r\n /**\r\n * Style classes\r\n */\r\n static get CSS() {\r\n return {\r\n toolbox: \"tc-toolbox\",\r\n toolboxShowed: \"tc-toolbox--showed\",\r\n toggler: \"tc-toolbox__toggler\",\r\n };\r\n }\r\n\r\n /**\r\n * Returns rendered Toolbox element\r\n */\r\n get element() {\r\n return this.wrapper;\r\n }\r\n\r\n /**\r\n * Creating a toolbox to open menu for a manipulating columns\r\n *\r\n * @returns {Element}\r\n */\r\n createToolbox() {\r\n const wrapper = $.make(\"div\", [\r\n Toolbox.CSS.toolbox,\r\n this.cssModifier ? `${Toolbox.CSS.toolbox}--${this.cssModifier}` : \"\",\r\n ]);\r\n\r\n wrapper.dataset.mutationFree = \"true\";\r\n const popover = this.createPopover();\r\n const toggler = this.createToggler();\r\n\r\n wrapper.appendChild(toggler);\r\n wrapper.appendChild(popover);\r\n\r\n return wrapper;\r\n }\r\n\r\n /**\r\n * Creates the Toggler\r\n *\r\n * @returns {Element}\r\n */\r\n createToggler() {\r\n const toggler = $.make(\"div\", Toolbox.CSS.toggler, {\r\n innerHTML: IconMenuSmall,\r\n });\r\n\r\n toggler.addEventListener(\"click\", () => {\r\n this.togglerClicked();\r\n });\r\n\r\n return toggler;\r\n }\r\n\r\n /**\r\n * Creates the Popover instance and render it\r\n *\r\n * @returns {Element}\r\n */\r\n createPopover() {\r\n this.popover = new Popover({\r\n items: this.items,\r\n });\r\n\r\n return this.popover.render();\r\n }\r\n\r\n /**\r\n * Toggler click handler. Opens/Closes the popover\r\n *\r\n * @returns {void}\r\n */\r\n togglerClicked() {\r\n if (this.popover?.opened) {\r\n this.popover.close();\r\n this.onClose();\r\n } else {\r\n this.popover?.open();\r\n this.onOpen();\r\n }\r\n }\r\n\r\n /**\r\n * Shows the Toolbox\r\n *\r\n * @param {function} computePositionMethod - method that returns the position coordinate\r\n * @returns {void}\r\n */\r\n show(computePositionMethod:Function) {\r\n const position = computePositionMethod();\r\n\r\n /**\r\n * Set 'top' or 'left' style\r\n */\r\n Object.entries(position).forEach(([prop, value]) => {\r\n //this.wrapper.style[prop] = value;\r\n this.wrapper.style.setProperty(prop, value as string);\r\n });\r\n\r\n this.wrapper.classList.add(Toolbox.CSS.toolboxShowed);\r\n }\r\n\r\n /**\r\n * Hides the Toolbox\r\n *\r\n * @returns {void}\r\n */\r\n hide() {\r\n this.popover?.close();\r\n this.wrapper.classList.remove(Toolbox.CSS.toolboxShowed);\r\n }\r\n}\r\n","import Toolbox from './toolbox';\r\nimport * as $ from './utils/dom';\r\nimport throttled from './utils/throttled';\r\n\r\nimport {\r\n IconDirectionLeftDown,\r\n IconDirectionRightDown,\r\n IconDirectionUpRight,\r\n IconDirectionDownRight,\r\n IconCross,\r\n\r\n} from '../../icons';\r\ntype TableData = {\r\n /**\r\n * - number of rows in the table\r\n */\r\n /**\r\n * - number of rows in the table\r\n */\r\n rows: number;\r\n /**\r\n * - number of columns in the table\r\n */\r\n /**\r\n * - number of columns in the table\r\n */\r\n cols: number;\r\n colWidth: string[];\r\n}\r\nconst CSS = {\r\n wrapper: 'tc-wrap',\r\n wrapperReadOnly: 'tc-wrap--readonly',\r\n table: 'tc-table',\r\n row: 'tc-row',\r\n withHeadings: 'tc-table--heading',\r\n rowSelected: 'tc-row--selected',\r\n cell: 'tc-cell',\r\n cellSelected: 'tc-cell--selected',\r\n addRow: 'tc-add-row',\r\n addRowDisabled: 'tc-add-row--disabled',\r\n addColumn: 'tc-add-column',\r\n addColumnDisabled: 'tc-add-column--disabled',\r\n};\r\n\r\n/**\r\n * @typedef {object} TableConfig\r\n * @description Tool's config from Editor\r\n * @property {boolean} withHeadings — Uses the first line as headings\r\n * @property {string[][]} withHeadings — two-dimensional array with table contents\r\n */\r\n\r\n/**\r\n * @typedef {object} TableData - object with the data transferred to form a table\r\n * @property {number} rows - number of rows in the table\r\n * @property {number} cols - number of columns in the table\r\n */\r\n\r\n\r\n/**\r\n * Generates and manages table contents.\r\n */\r\nexport default class Table {\r\n\r\n private readOnly: boolean;\r\n private api: any;\r\n private data: any;\r\n private config: any;\r\n private wrapper: any;\r\n private table: any;\r\n private toolboxColumn: any;\r\n private toolboxRow: any;\r\n private documentClicked: any;\r\n private hoveredRow: any;\r\n private hoveredColumn: any;\r\n private selectedRow: any;\r\n private selectedColumn: any;\r\n private tunes: any;\r\n private focusedCell: any;\r\n\r\n private hoveredCell: any;\r\n private isDragging: boolean;\r\n //private draggingRow: number;\r\n private draggingColumn: number;\r\n //private draggingColArr: any[];\r\n private startWidth: number;\r\n private mouseStartX: number;\r\n private colWidthArr:any[];\r\n private minCellWidhth: number=50;\r\n private defaultCellWidth = 100;\r\n /**\r\n * Creates\r\n *\r\n * @constructor\r\n * @param {boolean} readOnly - read-only mode flag\r\n * @param {object} api - Editor.js API\r\n * @param {TableData} data - Editor.js API\r\n * @param {TableConfig} config - Editor.js API\r\n */\r\n constructor(readOnly: boolean, api: any, data: TableData, config: any) {\r\n this.readOnly = readOnly;\r\n this.api = api;\r\n this.data = data;\r\n this.config = config;\r\n\r\n /**\r\n * DOM nodes\r\n */\r\n this.wrapper = null;\r\n this.table = null;\r\n this.hoveredCell = null;\r\n\r\n this.isDragging = false;\r\n //this.draggingColArr = [];\r\n //this.draggingRow = 0;\r\n this.draggingColumn = 0;\r\n this.startWidth = 0;\r\n this.mouseStartX = 0;\r\n this.colWidthArr = [];\r\n \r\n\r\n // 鼠标焦点数据\r\n this.focusedCell = {\r\n row: 0,\r\n col: 0,\r\n };\r\n /**\r\n * Toolbox for managing of columns\r\n */\r\n this.toolboxColumn = this.createColumnToolbox();\r\n this.toolboxRow = this.createRowToolbox();\r\n\r\n /**\r\n * Create table and wrapper elements\r\n */\r\n this.createTableWrapper();\r\n\r\n // Current hovered row index\r\n this.hoveredRow = 0;\r\n\r\n // Current hovered column index\r\n this.hoveredColumn = 0;\r\n\r\n // Index of last selected row via toolbox\r\n this.selectedRow = 0;\r\n\r\n // Index of last selected column via toolbox\r\n this.selectedColumn = 0;\r\n\r\n // Additional settings for the table\r\n this.tunes = {\r\n withHeadings: false\r\n };\r\n\r\n /**\r\n * Resize table to match config/data size\r\n */\r\n this.resize();\r\n if(this.data.colWidth.length > 0) {\r\n this.colWidthArr = this.data.colWidth;\r\n }\r\n this.updateColWidth();\r\n /**\r\n * Fill the table with data\r\n */\r\n this.fill();\r\n\r\n /**\r\n * The cell in which the focus is currently located, if 0 and 0 then there is no focus\r\n * Uses to switch between cells with buttons\r\n */\r\n this.focusedCell = {\r\n row: 0,\r\n column: 0\r\n };\r\n\r\n /**\r\n * Global click listener allows to delegate clicks on some elements\r\n */\r\n this.documentClicked = (event: MouseEvent) => {\r\n let target = event.target as HTMLElement;\r\n const clickedInsideTable = target.closest(`.${CSS.table}`) !== null;\r\n const outsideTableClicked = target.closest(`.${CSS.wrapper}`) === null;\r\n const clickedOutsideToolboxes = clickedInsideTable || outsideTableClicked;\r\n\r\n if (clickedOutsideToolboxes) {\r\n this.hideToolboxes();\r\n }\r\n\r\n const clickedOnAddRowButton = target.closest(`.${CSS.addRow}`);\r\n const clickedOnAddColumnButton = target.closest(`.${CSS.addColumn}`);\r\n\r\n /**\r\n * Also, check if clicked in current table, not other (because documentClicked bound to the whole document)\r\n */\r\n if (clickedOnAddRowButton && clickedOnAddRowButton.parentNode === this.wrapper) {\r\n this.addRow(undefined, true);\r\n this.hideToolboxes();\r\n } else if (clickedOnAddColumnButton && clickedOnAddColumnButton.parentNode === this.wrapper) {\r\n this.addColumn(undefined, true);\r\n this.hideToolboxes();\r\n }\r\n };\r\n\r\n if (!this.readOnly) {\r\n this.bindEvents();\r\n }\r\n }\r\n\r\n /**\r\n * Returns the rendered table wrapper\r\n *\r\n * @returns {Element}\r\n */\r\n getWrapper() {\r\n return this.wrapper;\r\n }\r\n\r\n /**\r\n * Hangs the necessary handlers to events\r\n */\r\n bindEvents() {\r\n // set the listener to close toolboxes when click outside\r\n document.addEventListener('click', this.documentClicked);\r\n// 鼠标点击事件:判定是否在表格内部\r\n document.addEventListener(\"mousedown\", (e) =>\r\n this.handleDocumentMousedown(e)\r\n );\r\n // Update toolboxes position depending on the mouse movements\r\n this.table.addEventListener('mousemove', throttled(150, (event:MouseEvent) => this.onMouseMoveInTable(event)), { passive: true });\r\n\r\n // Controls some of the keyboard buttons inside the table\r\n this.table.onkeypress = (event:KeyboardEvent) => this.onKeyPressListener(event);\r\n\r\n // Tab is executed by default before keypress, so it must be intercepted on keydown\r\n this.table.addEventListener('keydown', (event:KeyboardEvent) => this.onKeyDownListener(event));\r\n\r\n // Determine the position of the cell in focus\r\n this.table.addEventListener('focusin', (event:FocusEvent) => this.focusInTableListener(event));\r\n }\r\nhandleDocumentMousedown = (e:MouseEvent) => {\r\n // 在表格内部按下鼠标并且处于拖拽位置\r\n if (this.wrapper.contains(e.target)) {\r\n const target = e.target as HTMLElement;\r\n if (target.classList.contains(\"cell-resizable\")) {\r\n e.preventDefault();\r\n //this.hideToolbox(); // 拖拽时隐藏工具栏\r\n this.isDragging = true;\r\n this.table.classList.add(\"table-resizing\"); //为整个表格添加光标样式\r\n document.addEventListener(\"mousemove\", this.handleDocumentMousemove);\r\n document.addEventListener(\"mouseup\", this.handleDocumentMouseup);\r\n //this.draggingRow = this.hoveredRow;\r\n this.draggingColumn = this.hoveredColumn;\r\n //this.draggingColArr = this.getCellInCol(this.draggingColumn);\r\n this.startWidth = this.colWidthArr[this.draggingColumn - 1]; //获取初始宽度\r\n this.mouseStartX = e.clientX;\r\n }\r\n } else {\r\n //this.hideToolbox();\r\n }\r\n };\r\n // 获取同一列的所有单元格\r\n getCellInCol(col:number) {\r\n const cells:any[] = [];\r\n const rows = this.table.querySelectorAll(`.${CSS.row}`);\r\n rows.forEach((row:Element) => {\r\n const cell = row.querySelector(`.${CSS.cell}:nth-child(${col})`);\r\n if (cell) cells.push(cell);\r\n });\r\n return cells;\r\n }\r\n // mousemove事件\r\n handleDocumentMousemove = (e:MouseEvent) => {\r\n if (!this.isDragging) return;\r\n const currentMouseX = e.clientX;\r\n const deltaX = currentMouseX - this.mouseStartX;\r\n const newWidth = Math.max(this.startWidth + deltaX, this.minCellWidhth);\r\n\r\n this.colWidthArr[this.draggingColumn - 1] = newWidth;\r\n this.updateColWidth();\r\n };\r\n // mouseup事件\r\n handleDocumentMouseup = () => {\r\n //this.showToolbox(); // 拖拽结束时重新显示工具栏\r\n //this.updateToolboxPosition();\r\n this.updateToolboxesPosition();\r\n this.isDragging = false;\r\n this.table.classList.remove(\"table-resizing\");\r\n document.removeEventListener(\"mousemove\", this.handleDocumentMousemove);\r\n document.removeEventListener(\"mouseup\", this.handleDocumentMouseup);\r\n };\r\n /**\r\n * Configures and creates the toolbox for manipulating with columns\r\n *\r\n * @returns {Toolbox}\r\n */\r\n createColumnToolbox() {\r\n return new Toolbox({\r\n api: this.api,\r\n cssModifier: 'column',\r\n items: [\r\n {\r\n label: this.api.i18n.t('Add column to left'),\r\n icon: IconDirectionLeftDown,\r\n hideIf: () => {\r\n return this.numberOfColumns === this.config.maxcols\r\n },\r\n onClick: () => { \r\n this.addColumn(this.selectedColumn, true);\r\n this.hideToolboxes();\r\n this.updateColWidth();\r\n }\r\n },\r\n {\r\n label: this.api.i18n.t('Add column to right'),\r\n icon: IconDirectionRightDown,\r\n hideIf: () => {\r\n return this.numberOfColumns === this.config.maxcols\r\n },\r\n onClick: () => {\r\n this.addColumn(this.selectedColumn + 1, true);\r\n this.hideToolboxes();\r\n this.updateColWidth();\r\n }\r\n },\r\n {\r\n label: this.api.i18n.t('Delete column'),\r\n icon: IconCross,\r\n hideIf: () => {\r\n return this.numberOfColumns === 1;\r\n },\r\n confirmationRequired: true,\r\n onClick: () => {\r\n this.deleteColumn(this.selectedColumn);\r\n this.hideToolboxes();\r\n this.updateColWidth();\r\n }\r\n }\r\n ],\r\n onOpen: () => {\r\n this.selectColumn(this.hoveredColumn);\r\n this.hideRowToolbox();\r\n },\r\n onClose: () => {\r\n this.unselectColumn();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Configures and creates the toolbox for manipulating with rows\r\n *\r\n * @returns {Toolbox}\r\n */\r\n createRowToolbox() {\r\n return new Toolbox({\r\n api: this.api,\r\n cssModifier: 'row',\r\n items: [\r\n {\r\n label: this.api.i18n.t('Add row above'),\r\n icon: IconDirectionUpRight,\r\n hideIf: () => {\r\n return this.numberOfRows === this.config.maxrows\r\n },\r\n onClick: () => {\r\n this.addRow(this.selectedRow, true);\r\n this.hideToolboxes();\r\n }\r\n },\r\n {\r\n label: this.api.i18n.t('Add row below'),\r\n icon: IconDirectionDownRight,\r\n hideIf: () => {\r\n return this.numberOfRows === this.config.maxrows\r\n },\r\n onClick: () => {\r\n this.addRow(this.selectedRow + 1, true);\r\n this.hideToolboxes();\r\n }\r\n },\r\n {\r\n label: this.api.i18n.t('Delete row'),\r\n icon: IconCross,\r\n hideIf: () => {\r\n return this.numberOfRows === 1;\r\n },\r\n confirmationRequired: true,\r\n onClick: () => {\r\n this.deleteRow(this.selectedRow);\r\n this.hideToolboxes();\r\n }\r\n }\r\n ],\r\n onOpen: () => {\r\n this.selectRow(this.hoveredRow);\r\n this.hideColumnToolbox();\r\n },\r\n onClose: () => {\r\n this.unselectRow();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * When you press enter it moves the cursor down to the next row\r\n * or creates it if the click occurred on the last one\r\n */\r\n moveCursorToNextRow() {\r\n if (this.focusedCell.row !== this.numberOfRows) {\r\n this.focusedCell.row += 1;\r\n //this.focusCell(this.focusedCell);\r\n this.focusCell();\r\n } else {\r\n this.addRow();\r\n this.focusedCell.row += 1;\r\n //this.focusCell(this.focusedCell);\r\n this.focusCell();\r\n this.updateToolboxesPosition(0, 0);\r\n }\r\n }\r\n\r\n /**\r\n * Get table cell by row and col index\r\n *\r\n * @param {number} row - cell row coordinate\r\n * @param {number} column - cell column coordinate\r\n * @returns {HTMLElement}\r\n */\r\n getCell(row:number, column:number) {\r\n return this.table.querySelectorAll(`.${CSS.row}:nth-child(${row}) .${CSS.cell}`)[column - 1];\r\n }\r\n\r\n /**\r\n * Get table row by index\r\n *\r\n * @param {number} row - row coordinate\r\n * @returns {HTMLElement}\r\n */\r\n getRow(row:number) {\r\n return this.table.querySelector(`.${CSS.row}:nth-child(${row})`);\r\n }\r\n\r\n /**\r\n * The parent of the cell which is the row\r\n *\r\n * @param {HTMLElement} cell - cell element\r\n * @returns {HTMLElement}\r\n */\r\n getRowByCell(cell:HTMLElement) {\r\n return cell.parentElement;\r\n }\r\n\r\n /**\r\n * Ger row's first cell\r\n *\r\n * @param {Element} row - row to find its first cell\r\n * @returns {Element}\r\n */\r\n getRowFirstCell(row:Element) {\r\n return row.querySelector(`.${CSS.cell}:first-child`);\r\n }\r\n\r\n /**\r\n * Set the sell's content by row and column numbers\r\n *\r\n * @param {number} row - cell row coordinate\r\n * @param {number} column - cell column coordinate\r\n * @param {string} content - cell HTML content\r\n */\r\n setCellContent(row:number, column:number, content:string) {\r\n const cell = this.getCell(row, column);\r\n\r\n cell.innerHTML = content;\r\n }\r\n\r\n /**\r\n * Add column in table on index place\r\n * Add cells in each row\r\n *\r\n * @param {number} columnIndex - number in the array of columns, where new column to insert, -1 if insert at the end\r\n * @param {boolean} [setFocus] - pass true to focus the first cell\r\n */\r\n addColumn(columnIndex = -1, setFocus = false) {\r\n let numOfColumns=this.numberOfColumns;\r\n /**\r\n * Check if the number of columns has reached the maximum allowed columns specified in the configuration,\r\n * and if so, exit the function to prevent adding more columns beyond the limit.\r\n */\r\n if (this.config && this.config.maxcols && this.numberOfColumns >= this.config.maxcols) {\r\n return;\r\n }\r\n\r\n /**\r\n * Iterate all rows and add a new cell to them for creating a column\r\n */\r\n for (let rowIndex = 1; rowIndex <= this.numberOfRows; rowIndex++) {\r\n let cell;\r\n const cellElem = this.createCell();\r\n\r\n if (columnIndex > 0 && columnIndex <= numOfColumns) {\r\n cell = this.getCell(rowIndex, columnIndex);\r\n\r\n $.insertBefore(cellElem, cell);\r\n } else {\r\n cell = this.getRow(rowIndex).appendChild(cellElem);\r\n }\r\n\r\n /**\r\n * Autofocus first cell\r\n */\r\n if (rowIndex === 1) {\r\n const firstCell = this.getCell(rowIndex, columnIndex > 0 ? columnIndex : numOfColumns + 1);\r\n\r\n if (firstCell && setFocus) {\r\n $.focus(firstCell);\r\n }\r\n }\r\n }\r\n\r\n const addColButton = this.wrapper.querySelector(`.${CSS.addColumn}`);\r\n if (this.config?.maxcols && this.numberOfColumns > this.config.maxcols - 1 && addColButton ){\r\n addColButton.classList.add(CSS.addColumnDisabled);\r\n }\r\n this.addHeadingAttrToFirstRow();\r\n this.colWidthArr.splice(columnIndex - 1, 0, this.defaultCellWidth);\r\n };\r\n\r\n /**\r\n * Add row in table on index place\r\n *\r\n * @param {number} index - number in the array of rows, where new column to insert, -1 if insert at the end\r\n * @param {boolean} [setFocus] - pass true to focus the inserted row\r\n * @returns {HTMLElement} row\r\n */\r\n addRow(index = -1, setFocus = false) {\r\n let insertedRow;\r\n let rowElem = $.make('div', CSS.row);\r\n\r\n if (this.tunes.withHeadings) {\r\n this.removeHeadingAttrFromFirstRow();\r\n }\r\n\r\n /**\r\n * We remember the number of columns, because it is calculated\r\n * by the number of cells in the first row\r\n * It is necessary that the first line is filled in correctly\r\n */\r\n let numberOfColumns = this.numberOfColumns;\r\n /**\r\n * Check if the number of rows has reached the maximum allowed rows specified in the configuration,\r\n * and if so, exit the function to prevent adding more columns beyond the limit.\r\n */ \r\n if (this.config && this.config.maxrows && this.numberOfRows >= this.config.maxrows ) {\r\n return;\r\n }\r\n\r\n if (index > 0 && index <= this.numberOfRows) {\r\n let row = this.getRow(index);\r\n\r\n insertedRow = $.insertBefore(rowElem, row);\r\n } else {\r\n insertedRow = this.table.appendChild(rowElem);\r\n }\r\n\r\n this.fillRow(insertedRow, numberOfColumns);\r\n\r\n if (this.tunes.withHeadings) {\r\n this.addHeadingAttrToFirstRow();\r\n }\r\n\r\n const insertedRowFirstCell = this.getRowFirstCell(insertedRow);\r\n\r\n if (insertedRowFirstCell && setFocus) {\r\n $.focus(insertedRowFirstCell as HTMLElement);\r\n }\r\n\r\n const addRowButton = this.wrapper.querySelector(`.${CSS.addRow}`);\r\n if (this.config && this.config.maxrows && this.numberOfRows >= this.config.maxrows && addRowButton) {\r\n addRowButton.classList.add(CSS.addRowDisabled);\r\n }\r\n return insertedRow;\r\n };\r\n\r\n /**\r\n * Delete a column by index\r\n *\r\n * @param {number} index\r\n */\r\n deleteColumn(index: number) {\r\n for (let i = 1; i <= this.numberOfRows; i++) {\r\n const cell = this.getCell(i, index);\r\n\r\n if (!cell) {\r\n return;\r\n }\r\n\r\n cell.remove();\r\n }\r\n const addColButton = this.wrapper.querySelector(`.${CSS.addColumn}`);\r\n if (addColButton) {\r\n addColButton.classList.remove(CSS.addColumnDisabled);\r\n }\r\n this.colWidthArr.splice(index - 1, 1);\r\n }\r\n\r\n /**\r\n * Delete a row by index\r\n *\r\n * @param {number} index\r\n */\r\n deleteRow(index: number) {\r\n this.getRow(index).remove();\r\n const addRowButton = this.wrapper.querySelector(`.${CSS.addRow}`);\r\n if (addRowButton) {\r\n addRowButton.classList.remove(CSS.addRowDisabled);\r\n }\r\n\r\n this.addHeadingAttrToFirstRow();\r\n }\r\n\r\n /**\r\n * Create a wrapper containing a table, toolboxes\r\n * and buttons for adding rows and columns\r\n *\r\n * @returns {HTMLElement} wrapper - where all buttons for a table and the table itself will be\r\n */\r\n createTableWrapper() {\r\n this.wrapper = $.make('div', CSS.wrapper);\r\n this.table = $.make('div', CSS.table);\r\n\r\n if (this.readOnly) {\r\n this.wrapper.classList.add(CSS.wrapperReadOnly);\r\n }\r\n\r\n this.wrapper.appendChild(this.toolboxRow.element);\r\n this.wrapper.appendChild(this.toolboxColumn.element);\r\n this.wrapper.appendChild(this.table);\r\n\r\n // if (!this.readOnly) {\r\n // const addColumnButton = $.make('div', CSS.addColumn, {\r\n // innerHTML: IconPlus\r\n // });\r\n // const addRowButton = $.make('div', CSS.addRow, {\r\n // innerHTML: IconPlus\r\n // });\r\n\r\n // this.wrapper.appendChild(addColumnButton);\r\n // this.wrapper.appendChild(addRowButton);\r\n // }\r\n }\r\n\r\n /**\r\n * Returns the size of the table based on initial data or config \"size\" property\r\n *\r\n * @return {{rows: number, cols: number}} - number of cols and rows\r\n */\r\n computeInitialSize() {\r\n const content = this.data && this.data.content;\r\n const isValidArray = Array.isArray(content);\r\n const isNotEmptyArray = isValidArray ? content.length : false;\r\n const contentRows = isValidArray ? content.length : undefined;\r\n const contentCols = isNotEmptyArray ? content[0].length : undefined;\r\n const parsedRows = Number.parseInt(this.config && this.config.rows);\r\n const parsedCols = Number.parseInt(this.config && this.config.cols);\r\n\r\n /**\r\n * Value of config have to be positive number\r\n */\r\n const configRows = !isNaN(parsedRows) && parsedRows > 0 ? parsedRows : undefined;\r\n const configCols = !isNaN(parsedCols) && parsedCols > 0 ? parsedCols : undefined;\r\n const defaultRows = 2;\r\n const defaultCols = 2;\r\n const rows = contentRows || configRows || defaultRows;\r\n const cols = contentCols || configCols || defaultCols;\r\n\r\n return {\r\n rows: rows,\r\n cols: cols\r\n };\r\n }\r\n\r\n /**\r\n * Resize table to match config size or transmitted data size\r\n *\r\n * @return {{rows: number, cols: number}} - number of cols and rows\r\n */\r\n resize() {\r\n const { rows, cols } = this.computeInitialSize();\r\n\r\n for (let i = 0; i < rows; i++) {\r\n this.addRow();\r\n }\r\n\r\n for (let i = 0; i < cols; i++) {\r\n this.addColumn();\r\n }\r\n\r\n \r\n }\r\n updateColWidth() {\r\n //设置各列宽度\r\n let colWidth = \"\";\r\n if (this.colWidthArr && this.colWidthArr.length > 0) {\r\n for (let i = 0; i < this.colWidthArr.length; i++) {\r\n colWidth += \" \" + this.colWidthArr[i] + \"px\";\r\n }\r\n }\r\n if (colWidth) {\r\n this.wrapper.style.setProperty('--col-width', colWidth);\r\n }\r\n \r\n }\r\n\r\n /**\r\n * Fills the table with data passed to the constructor\r\n *\r\n * @returns {void}\r\n */\r\n fill() {\r\n const data = this.data;\r\n\r\n if (data && data.content) {\r\n for (let i = 0; i < data.content.length; i++) {\r\n for (let j = 0; j < data.content[i].length; j++) {\r\n this.setCellContent(i + 1, j + 1, data.content[i][j]);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Fills a row with cells\r\n *\r\n * @param {HTMLElement} row - row to fill\r\n * @param {number} numOfColumns - how many cells should be in a row\r\n */\r\n fillRow(row:HTMLElement, numOfColumns:number) {\r\n for (let i = 1; i <= numOfColumns; i++) {\r\n const newCell = this.createCell();\r\n\r\n row.appendChild(newCell);\r\n }\r\n }\r\n\r\n /**\r\n * Creating a cell element\r\n *\r\n * @return {Element}\r\n */\r\n createCell() {\r\n return $.make('div', CSS.cell, {\r\n contentEditable: !this.readOnly\r\n });\r\n }\r\n\r\n /**\r\n * Get number of rows in the table\r\n */\r\n get numberOfRows() {\r\n return this.table.childElementCount;\r\n }\r\n\r\n /**\r\n * Get number of columns in the table\r\n */\r\n get numberOfColumns() {\r\n if (this.numberOfRows) {\r\n return this.table.querySelectorAll(`.${CSS.row}:first-child .${CSS.cell}`).length;\r\n }\r\n\r\n return 0;\r\n }\r\n\r\n /**\r\n * Is the column toolbox menu displayed or not\r\n *\r\n * @returns {boolean}\r\n */\r\n get isColumnMenuShowing() {\r\n return this.selectedColumn !== 0;\r\n }\r\n\r\n /**\r\n * Is the row toolbox menu displayed or not\r\n *\r\n * @returns {boolean}\r\n */\r\n get isRowMenuShowing() {\r\n return this.selectedRow !== 0;\r\n }\r\n\r\n /**\r\n * Recalculate position of toolbox icons\r\n *\r\n * @param {Event} event - mouse move event\r\n */\r\n onMouseMoveInTable(event:MouseEvent) {\r\n const { row, column, deltaXCell } = this.getHoveredCell(event);\r\n\r\n this.hoveredColumn = column;\r\n this.hoveredRow = row;\r\n\r\n this.updateToolboxesPosition();\r\n\r\n if (this.hoveredCell !== null && this.hoveredCell.classList.contains(\"cell-resizable\")) {\r\n this.hoveredCell.classList.remove(\"cell-resizable\");\r\n }\r\n this.hoveredCell = this.getCell(row, column);\r\n \r\n // 判断是否可以调整列宽\r\n if (this.cellIsResizable(this.hoveredCell, deltaXCell)) {\r\n // 将鼠标改为拖拽光标\r\n if (!this.hoveredCell.classList.contains(\"cell-resizable\"))\r\n this.hoveredCell.classList.add(\"cell-resizable\");\r\n }\r\n\r\n }\r\n cellIsResizable(cell: HTMLElement, deltaX: number) {\r\n // 判断光标是否在单元格右侧10px的位置\r\n const cellWidth = cell.clientWidth;\r\n return cellWidth - deltaX <= 10;\r\n }\r\n /**\r\n * Prevents default Enter behaviors\r\n * Adds Shift+Enter processing\r\n *\r\n * @param {KeyboardEvent} event - keypress event\r\n */\r\n onKeyPressListener(event: KeyboardEvent) {\r\n if (event.key === 'Enter') {\r\n if (event.shiftKey) {\r\n return true;\r\n }\r\n\r\n this.moveCursorToNextRow();\r\n }\r\n\r\n return event.key !== 'Enter';\r\n };\r\n\r\n /**\r\n * Prevents tab keydown event from bubbling\r\n * so that it only works inside the table\r\n *\r\n * @param {KeyboardEvent} event - keydown event\r\n */\r\n onKeyDownListener(event: KeyboardEvent) {\r\n if (event.key === 'Tab') {\r\n event.stopPropagation();\r\n }\r\n }\r\n\r\n /**\r\n * Set the coordinates of the cell that the focus has moved to\r\n *\r\n * @param {FocusEvent} event - focusin event\r\n */\r\n focusInTableListener(event: FocusEvent) {\r\n const cell = event.target as HTMLElement;\r\n const row = this.getRowByCell(cell);\r\n if(!row) return;\r\n\r\n this.focusedCell = {\r\n row: Array.from(this.table.querySelectorAll(`.${CSS.row}`)).indexOf(row) + 1,\r\n column: Array.from(row.querySelectorAll(`.${CSS.cell}`)).indexOf(cell) + 1\r\n };\r\n }\r\n\r\n /**\r\n * Unselect row/column\r\n * Close toolbox menu\r\n * Hide toolboxes\r\n *\r\n * @returns {void}\r\n */\r\n hideToolboxes() {\r\n this.hideRowToolbox();\r\n this.hideColumnToolbox();\r\n this.updateToolboxesPosition();\r\n }\r\n\r\n /**\r\n * Unselect row, close toolbox\r\n *\r\n * @returns {void}\r\n */\r\n hideRowToolbox() {\r\n this.unselectRow();\r\n this.toolboxRow.hide();\r\n }\r\n /**\r\n * Unselect column, close toolbox\r\n *\r\n * @returns {void}\r\n */\r\n hideColumnToolbox() {\r\n this.unselectColumn();\r\n\r\n this.toolboxColumn.hide();\r\n }\r\n\r\n /**\r\n * Set the cursor focus to the focused cell\r\n *\r\n * @returns {void}\r\n */\r\n focusCell() {\r\n this.focusedCellElem.focus();\r\n }\r\n\r\n /**\r\n * Get current focused element\r\n *\r\n * @returns {HTMLElement} - focused cell\r\n */\r\n get focusedCellElem() {\r\n const { row, column } = this.focusedCell;\r\n\r\n return this.getCell(row, column);\r\n }\r\n\r\n /**\r\n * Update toolboxes position\r\n *\r\n * @param {number} row - hovered row\r\n * @param {number} column - hovered column\r\n */\r\n updateToolboxesPosition(row = this.hoveredRow, column = this.hoveredColumn) {\r\n if (!this.isColumnMenuShowing) {\r\n if (column > 0 && column <= this.numberOfColumns) { // not sure this statement is needed. Maybe it should be fixed in getHoveredCell()\r\n this.toolboxColumn.show(() => {\r\n return {\r\n left: `calc((100% - var(--cell-size)) / (${this.numberOfColumns} * 2) * (1 + (${column} - 1) * 2))`\r\n };\r\n });\r\n }\r\n }\r\n\r\n if (!this.isRowMenuShowing) {\r\n if (row > 0 && row <= this.numberOfRows) { // not sure this statement is needed. Maybe it should be fixed in getHoveredCell()\r\n this.toolboxRow.show(() => {\r\n const hoveredRowElement = this.getRow(row);\r\n const { fromTopBorder } = $.getRelativeCoordsOfTwoElems(this.table, hoveredRowElement);\r\n const { height } = hoveredRowElement.getBoundingClientRect();\r\n\r\n return {\r\n top: `${Math.ceil(fromTopBorder + height / 2)}px`\r\n };\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Makes the first row headings\r\n *\r\n * @param {boolean} withHeadings - use headings row or not\r\n */\r\n setHeadingsSetting(withHeadings: boolean) {\r\n this.tunes.withHeadings = withHeadings;\r\n\r\n if (withHeadings) {\r\n this.table.classList.add(CSS.withHeadings);\r\n this.addHeadingAttrToFirstRow();\r\n } else {\r\n this.table.classList.remove(CSS.withHeadings);\r\n this.removeHeadingAttrFromFirstRow();\r\n }\r\n }\r\n\r\n /**\r\n * Adds an attribute for displaying the placeholder in the cell\r\n */\r\n addHeadingAttrToFirstRow() {\r\n for (let cellIndex = 1; cellIndex <= this.numberOfColumns; cellIndex++) {\r\n let cell = this.getCell(1, cellIndex);\r\n\r\n if (cell) {\r\n cell.setAttribute('heading', this.api.i18n.t('Heading'));\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Removes an attribute for displaying the placeholder in the cell\r\n */\r\n removeHeadingAttrFromFirstRow() {\r\n for (let cellIndex = 1; cellIndex <= this.numberOfColumns; cellIndex++) {\r\n let cell = this.getCell(1, cellIndex);\r\n\r\n if (cell) {\r\n cell.removeAttribute('heading');\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Add effect of a selected row\r\n *\r\n * @param {number} index\r\n */\r\n selectRow(index: number) {\r\n const row = this.getRow(index);\r\n\r\n if (row) {\r\n this.selectedRow = index;\r\n row.classList.add(CSS.rowSelected);\r\n }\r\n }\r\n\r\n /**\r\n * Remove effect of a selected row\r\n */\r\n unselectRow() {\r\n if (this.selectedRow <= 0) {\r\n return;\r\n }\r\n\r\n const row = this.table.querySelector(`.${CSS.rowSelected}`);\r\n\r\n if (row) {\r\n row.classList.remove(CSS.rowSelected);\r\n }\r\n\r\n this.selectedRow = 0;\r\n }\r\n\r\n /**\r\n * Add effect of a selected column\r\n *\r\n * @param {number} index\r\n */\r\n selectColumn(index: number) {\r\n for (let i = 1; i <= this.numberOfRows; i++) {\r\n const cell = this.getCell(i, index);\r\n\r\n if (cell) {\r\n cell.classList.add(CSS.cellSelected);\r\n }\r\n }\r\n\r\n this.selectedColumn = index;\r\n }\r\n\r\n /**\r\n * Remove effect of a selected column\r\n */\r\n unselectColumn() {\r\n if (this.selectedColumn <= 0) {\r\n return;\r\n }\r\n\r\n let cells = this.table.querySelectorAll(`.${CSS.cellSelected}`) as HTMLElement[];\r\n\r\n Array.from(cells).forEach((column: HTMLElement) => {\r\n column.classList.remove(CSS.cellSelected);\r\n });\r\n\r\n this.selectedColumn = 0;\r\n }\r\n\r\n /**\r\n * Calculates the row and column that the cursor is currently hovering over\r\n * The search was optimized from O(n) to O (log n) via bin search to reduce the number of calculations\r\n *\r\n * @param {Event} event - mousemove event\r\n * @returns hovered cell coordinates as an integer row and column\r\n */\r\n getHoveredCell(event: MouseEvent) {\r\n let hoveredRow = this.hoveredRow;\r\n let hoveredColumn = this.hoveredColumn;\r\n const { width, height, x, y } = $.getCursorPositionRelativeToElement(this.table, event);\r\n \r\n\r\n \r\n // Looking for hovered column\r\n if (x >= 0) {\r\n const beforeTheLeftBorder1 = ({ fromLeftBorder }: { fromLeftBorder: number }) => x < fromLeftBorder;\r\n const afterTheRightBorder1 = ({ fromRightBorder }: { fromRightBorder: number }) => x > (width - fromRightBorder);\r\n hoveredColumn = this.binSearch(\r\n this.numberOfColumns,\r\n (mid: number) => this.getCell(1, mid),\r\n beforeTheLeftBorder1,\r\n afterTheRightBorder1\r\n );\r\n }\r\n\r\n // Looking for hovered row\r\n if (y >= 0) {\r\n const beforeTheLeftBorder2 = ({ fromTopBorder }: { fromTopBorder: number }) => y < fromTopBorder;\r\n const afterTheRightBorder2 = ({ fromBottomBorder }: { fromBottomBorder: number }) => y > (height - fromBottomBorder);\r\n hoveredRow = this.binSearch(\r\n this.numberOfRows,\r\n (mid: number) => this.getCell(mid, 1),\r\n beforeTheLeftBorder2,\r\n afterTheRightBorder2\r\n );\r\n }\r\n const row = hoveredRow || this.hoveredRow;\r\n const column = hoveredColumn || this.hoveredColumn;\r\n // 获取鼠标在单元格内的坐标\r\n const { deltaXCell, deltaYCell } = this.getMousePositionRelateToCell(\r\n row,\r\n column,\r\n x,\r\n y\r\n );\r\n\r\n return {\r\n row,\r\n column,\r\n deltaXCell,\r\n deltaYCell\r\n };\r\n }\r\n // 获取鼠标相对于单元格的坐标\r\n getMousePositionRelateToCell(row:number, col:number, deltaX:number, deltaY:number) {\r\n const cell = this.getCell(row, col);\r\n const { fromTopBorder, fromLeftBorder } = $.getRelativeCoordsOfTwoElems(\r\n this.table,\r\n cell\r\n );\r\n return {\r\n deltaXCell: deltaX - fromLeftBorder,\r\n deltaYCell: deltaY - fromTopBorder,\r\n };\r\n }\r\n /**\r\n * Looks for the index of the cell the mouse is hovering over.\r\n * Cells can be represented as ordered intervals with left and\r\n * right (upper and lower for rows) borders inside the table, if the mouse enters it, then this is our index\r\n *\r\n * @param {number} numberOfCells - upper bound of binary search\r\n * @param {function} getCell - function to take the currently viewed cell\r\n * @param {function} beforeTheLeftBorder - determines the cursor position, to the left of the cell or not\r\n * @param {function} afterTheRightBorder - determines the cursor position, to the right of the cell or not\r\n * @returns {number}\r\n */\r\n binSearch(numberOfCells: number, getCell: Function, beforeTheLeftBorder: Function, afterTheRightBorder: Function) {\r\n let leftBorder = 0;\r\n let rightBorder = numberOfCells + 1;\r\n let totalIterations = 0;\r\n let mid;\r\n\r\n while (leftBorder < rightBorder - 1 && totalIterations < 10) {\r\n mid = Math.ceil((leftBorder + rightBorder) / 2);\r\n\r\n const cell = getCell(mid);\r\n const relativeCoords = $.getRelativeCoordsOfTwoElems(this.table, cell);\r\n\r\n if (beforeTheLeftBorder(relativeCoords)) {\r\n rightBorder = mid;\r\n } else if (afterTheRightBorder(relativeCoords)) {\r\n leftBorder = mid;\r\n } else {\r\n break;\r\n }\r\n\r\n totalIterations++;\r\n }\r\n\r\n return mid;\r\n }\r\n\r\n /**\r\n * Collects data from cells into a two-dimensional array\r\n *\r\n * @returns {string[][]}\r\n */\r\n getData() {\r\n const data = [];\r\n\r\n for (let i = 1; i <= this.numberOfRows; i++) {\r\n const row = this.table.querySelector(`.${CSS.row}:nth-child(${i})`);\r\n const cells = Array.from(row.querySelectorAll(`.${CSS.cell}`));\r\n const isEmptyRow = cells.every((cell:any)=>!cell.textContent.trim());\r\n\r\n if (isEmptyRow) {\r\n continue;\r\n }\r\n\r\n data.push(cells.map((cell:any) => cell.innerHTML));\r\n }\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * Remove listeners on the document\r\n */\r\n destroy() {\r\n document.removeEventListener('click', this.documentClicked);\r\n }\r\n}","\r\n/**\r\n * Limits the frequency of calling a function\r\n *\r\n * @param {number} delay - delay between calls in milliseconds\r\n * @param {function} fn - function to be throttled\r\n */\r\nexport default function throttled(delay:number, fn:Function) {\r\n let lastCall = 0;\r\n\r\n return function (...args) {\r\n const now = new Date().getTime();\r\n\r\n if (now - lastCall < delay) {\r\n return;\r\n }\r\n\r\n lastCall = now;\r\n\r\n return fn(...args);\r\n };\r\n}\r\n","import Table from './table';\r\nimport * as $ from './utils/dom';\r\n\r\nimport { IconTable, IconTableWithHeadings, IconTableWithoutHeadings } from '../../icons';\r\nimport type { BlockTool, BlockToolConstructorOptions,PasteEvent } from '@ebl-vue/editorjs';\r\n\r\n/**\r\n * @typedef {object} TableData - configuration that the user can set for the table\r\n * @property {number} rows - number of rows in the table\r\n * @property {number} cols - number of columns in the table\r\n */\r\n/**\r\n * @typedef {object} Tune - setting for the table\r\n * @property {string} name - tune name\r\n * @property {HTMLElement} icon - icon for the tune\r\n * @property {boolean} isActive - default state of the tune\r\n * @property {void} setTune - set tune state to the table data\r\n */\r\n/**\r\n * @typedef {object} TableConfig - object with the data transferred to form a table\r\n * @property {boolean} withHeading - setting to use cells of the first row as headings\r\n * @property {string[][]} content - two-dimensional array which contains table content\r\n */\r\n/**\r\n * @typedef {object} TableConstructor\r\n * @property {TableConfig} data — previously saved data\r\n * @property {TableConfig} config - user config for Tool\r\n * @property {object} api - Editor.js API\r\n * @property {boolean} readOnly - read-only mode flag\r\n */\r\n/**\r\n * @typedef {import('@editorjs/editorjs').PasteEvent} PasteEvent\r\n */\r\n\r\n\r\n/**\r\n * Table block for Editor.js\r\n */\r\nexport default class TableBlock implements BlockTool {\r\n private api: any;\r\n private data: any;\r\n private config: any;\r\n private container: any;\r\n //private block: any;\r\n private readOnly: any;\r\n private table: any;\r\n \r\n /**\r\n * Notify core that read-only mode is supported\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isReadOnlySupported() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Allow to press Enter inside the CodeTool textarea\r\n *\r\n * @returns {boolean}\r\n * @public\r\n */\r\n static get enableLineBreaks() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Render plugin`s main Element and fill it with saved data\r\n *\r\n * @param {TableConstructor} init\r\n */\r\n constructor({ data, config, api, readOnly, block }: BlockToolConstructorOptions) {\r\n this.api = api;\r\n this.readOnly = readOnly;\r\n this.config = config;\r\n this.data = {\r\n withHeadings: this.getConfig('withHeadings', undefined, data),\r\n stretched: this.getConfig('stretched', undefined, data),\r\n content: data && data.content ? data.content : [],\r\n colWidth: data && data.colWidth ? data.colWidth : []\r\n };\r\n this.table = null;\r\n //this.block = block;\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n *\r\n * @returns {{icon: string, title: string}}\r\n */\r\n static get toolbox() {\r\n return {\r\n icon: IconTable,\r\n title: 'Table'\r\n };\r\n }\r\n\r\n /**\r\n * Return Tool's view\r\n *\r\n * @returns {HTMLDivElement}\r\n */\r\n render() {\r\n /** creating table */\r\n this.table = new Table(this.readOnly, this.api, this.data, this.config);\r\n\r\n /** creating container around table */\r\n this.container = $.make('div', this.api.styles.block);\r\n \r\n this.container.appendChild(this.table.getWrapper());\r\n\r\n this.table.setHeadingsSetting(this.data.withHeadings);\r\n\r\n return this.container;\r\n }\r\n\r\n /**\r\n * Returns plugin settings\r\n *\r\n * @returns {Array}\r\n */\r\n renderSettings() {\r\n return [\r\n {\r\n label: this.api.i18n.t('With headings'),\r\n icon: IconTableWithHeadings,\r\n isActive: this.data.withHeadings,\r\n closeOnActivate: true,\r\n toggle: true,\r\n hint: {\r\n title: this.api.i18n.t('With headings')\r\n },\r\n onActivate: () => {\r\n this.data.withHeadings = true;\r\n this.table.setHeadingsSetting(this.data.withHeadings);\r\n }\r\n }, {\r\n label: this.api.i18n.t('Without headings'),\r\n icon: IconTableWithoutHeadings,\r\n isActive: !this.data.withHeadings,\r\n closeOnActivate: true,\r\n toggle: true,\r\n hint: {\r\n title: this.api.i18n.t('Without headings')\r\n },\r\n onActivate: () => {\r\n this.data.withHeadings = false;\r\n this.table.setHeadingsSetting(this.data.withHeadings);\r\n }\r\n },\r\n // {\r\n // label: this.data.stretched ? this.api.i18n.t('Collapse') : this.api.i18n.t('Stretch'),\r\n // icon: this.data.stretched ? IconCollapse : IconStretch,\r\n // closeOnActivate: true,\r\n // toggle: true,\r\n // onActivate: () => {\r\n // this.data.stretched = !this.data.stretched;\r\n // this.block.stretched = this.data.stretched;\r\n // }\r\n // }\r\n ];\r\n }\r\n /**\r\n * Extract table data from the view\r\n *\r\n * @returns {TableData} - saved data\r\n */\r\n save() {\r\n const tableContent = this.table.getData();\r\n\r\n const result = {\r\n withHeadings: this.data.withHeadings,\r\n stretched: this.data.stretched,\r\n content: tableContent\r\n };\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Plugin destroyer\r\n *\r\n * @returns {void}\r\n */\r\n destroy() {\r\n this.table.destroy();\r\n }\r\n\r\n /**\r\n * A helper to get config value.\r\n *\r\n * @param {string} configName - the key to get from the config.\r\n * @param {any} defaultValue - default value if config doesn't have passed key\r\n * @param {object} savedData - previously saved data. If passed, the key will be got from there, otherwise from the config\r\n * @returns {any} - config value.\r\n */\r\n getConfig(configName: string, defaultValue = undefined, savedData = undefined) {\r\n const data = this.data || savedData;\r\n\r\n if (data) {\r\n return data[configName] ? data[configName] : defaultValue;\r\n }\r\n\r\n return this.config && this.config[configName] ? this.config[configName] : defaultValue;\r\n }\r\n\r\n /**\r\n * Table onPaste configuration\r\n *\r\n * @public\r\n */\r\n static get pasteConfig() {\r\n return { tags: ['TABLE', 'TR', 'TH', 'TD'] };\r\n }\r\n\r\n /**\r\n * On paste callback that is fired from Editor\r\n *\r\n * @param {PasteEvent} event - event with pasted data\r\n */\r\n onPaste(event: PasteEvent) {\r\n if ('data' in event.detail) {\r\n const table = event.detail.data as HTMLElement;\r\n\r\n /** Check if the first row is a header */\r\n const firstRowHeading = table.querySelector(':scope > thead, tr:first-of-type th');\r\n\r\n /** Get all rows from the table */\r\n const rows = Array.from(table.querySelectorAll('tr'));\r\n\r\n /** Generate a content matrix */\r\n const content = rows.map((row) => {\r\n /** Get cells from row */\r\n const cells = Array.from(row.querySelectorAll('th, td'))\r\n\r\n /** Return cells content */\r\n return cells.map((cell) => cell.innerHTML);\r\n });\r\n\r\n /** Update Tool's data */\r\n this.data = {\r\n withHeadings: firstRowHeading !== null,\r\n content\r\n };\r\n\r\n /** Update table block */\r\n if (this.table.wrapper) {\r\n this.table.wrapper.replaceWith(this.render());\r\n }\r\n }\r\n }\r\n}\r\n","/**\r\n * Helper for making Elements with attributes\r\n * @param tagName - new Element tag name\r\n * @param classNames - list or name of CSS class\r\n * @param attributes - any attributes\r\n * @returns\r\n */\r\nexport function make(tagName: string, classNames: string[] | string | null = null, attributes: { [key: string]: string | boolean } = {}): HTMLElement {\r\n const el = document.createElement(tagName);\r\n\r\n if (Array.isArray(classNames)) {\r\n el.classList.add(...classNames);\r\n } else if (classNames !== null) {\r\n el.classList.add(classNames);\r\n }\r\n\r\n for (const attrName in attributes) {\r\n if (attributes.hasOwnProperty(attrName)) {\r\n (el as unknown as { [key: string]: string | boolean })[attrName] = attributes[attrName];\r\n }\r\n }\r\n\r\n return el;\r\n}\r\n","import { IconPicture } from '../../icons';\r\nimport { make } from './utils/dom';\r\nimport type { API } from '@editorjs/editorjs';\r\nimport type { ImageConfig } from './types/types';\r\n\r\n/**\r\n * Enumeration representing the different states of the UI.\r\n */\r\nexport enum UiState {\r\n /**\r\n * The UI is in an empty state, with no image loaded or being selected.\r\n */\r\n Empty = 'empty',\r\n\r\n /**\r\n * The UI is in an uploading state, indicating an image is currently being uploaded.\r\n */\r\n Uploading = 'uploading',\r\n\r\n /**\r\n * The UI is in a filled state, with an image successfully loaded.\r\n */\r\n Filled = 'filled'\r\n};\r\n\r\n/**\r\n * Nodes interface representing various elements in the UI.\r\n */\r\ninterface Nodes {\r\n /**\r\n * Wrapper element in the UI.\r\n */\r\n wrapper: HTMLElement;\r\n\r\n /**\r\n * Container for the image element in the UI.\r\n */\r\n imageContainer: HTMLElement;\r\n\r\n /**\r\n * Button for selecting files.\r\n */\r\n fileButton: HTMLElement;\r\n\r\n /**\r\n * Represents the image element in the UI, if one is present; otherwise, it's undefined.\r\n */\r\n imageEl?: HTMLElement;\r\n\r\n /**\r\n * Preloader element for the image.\r\n */\r\n imagePreloader: HTMLElement;\r\n\r\n /**\r\n * Caption element for the image.\r\n */\r\n caption: HTMLElement;\r\n}\r\n\r\n/**\r\n * ConstructorParams interface representing parameters for the Ui class constructor.\r\n */\r\ninterface ConstructorParams {\r\n /**\r\n * Editor.js API.\r\n */\r\n api: API;\r\n /**\r\n * Configuration for the image.\r\n */\r\n config: ImageConfig;\r\n /**\r\n * Callback function for selecting a file.\r\n */\r\n onSelectFile: () => void;\r\n /**\r\n * Flag indicating if the UI is in read-only mode.\r\n */\r\n readOnly: boolean;\r\n}\r\n\r\n/**\r\n * Class for working with UI:\r\n * - rendering base structure\r\n * - show/hide preview\r\n * - apply tune view\r\n */\r\nexport default class Ui {\r\n /**\r\n * Nodes representing various elements in the UI.\r\n */\r\n public nodes: Nodes;\r\n\r\n /**\r\n * API instance for Editor.js.\r\n */\r\n private api: API;\r\n\r\n /**\r\n * Configuration for the image tool.\r\n */\r\n private config: ImageConfig;\r\n\r\n /**\r\n * Callback function for selecting a file.\r\n */\r\n private onSelectFile: () => void;\r\n\r\n /**\r\n * Flag indicating if the UI is in read-only mode.\r\n */\r\n private readOnly: boolean;\r\n\r\n /**\r\n * @param ui - image tool Ui module\r\n * @param ui.api - Editor.js API\r\n * @param ui.config - user config\r\n * @param ui.onSelectFile - callback for clicks on Select file button\r\n * @param ui.readOnly - read-only mode flag\r\n */\r\n constructor({ api, config, onSelectFile, readOnly }: ConstructorParams) {\r\n this.api = api;\r\n this.config = config;\r\n this.onSelectFile = onSelectFile;\r\n \r\n this.readOnly = readOnly;\r\n this.nodes = {\r\n wrapper: make('div', [this.CSS.baseClass, this.CSS.wrapper]),\r\n imageContainer: make('div', [this.CSS.imageContainer]),\r\n fileButton: this.createFileButton(),\r\n imageEl: undefined,\r\n imagePreloader: make('div', this.CSS.imagePreloader),\r\n caption: make('div', [this.CSS.input, this.CSS.caption], {\r\n contentEditable: !this.readOnly,\r\n }),\r\n };\r\n\r\n /**\r\n * Create base structure\r\n * <wrapper>\r\n * <image-container>\r\n * <image-preloader />\r\n * </image-container>\r\n * <caption />\r\n * <select-file-button />\r\n * </wrapper>\r\n */\r\n this.nodes.caption.dataset.placeholder = this.config.captionPlaceholder;\r\n this.nodes.imageContainer.appendChild(this.nodes.imagePreloader);\r\n this.nodes.wrapper.appendChild(this.nodes.imageContainer);\r\n this.nodes.wrapper.appendChild(this.nodes.caption);\r\n this.nodes.wrapper.appendChild(this.nodes.fileButton);\r\n }\r\n\r\n /**\r\n * Apply visual representation of activated tune\r\n * @param tuneName - one of available tunes {@link Tunes.tunes}\r\n * @param status - true for enable, false for disable\r\n */\r\n public applyTune(tuneName: string, status: boolean): void {\r\n this.nodes.wrapper.classList.toggle(`${this.CSS.wrapper}--${tuneName}`, status);\r\n }\r\n\r\n /**\r\n * Renders tool UI\r\n */\r\n public render(): HTMLElement {\r\n this.toggleStatus(UiState.Empty);\r\n\r\n return this.nodes.wrapper;\r\n }\r\n\r\n /**\r\n * Shows uploading preloader\r\n * @param src - preview source\r\n */\r\n public showPreloader(src: string): void {\r\n this.nodes.imagePreloader.style.backgroundImage = `url(${src})`;\r\n\r\n //this.toggleStatus(UiState.Uploading);\r\n }\r\n \r\n\r\n /**\r\n * Hide uploading preloader\r\n */\r\n public hidePreloader(): void {\r\n this.nodes.imagePreloader.style.backgroundImage = '';\r\n this.toggleStatus(UiState.Empty);\r\n }\r\n\r\n /**\r\n * Shows an image\r\n * @param url - image source\r\n */\r\n public fillImage(url: string): void {\r\n /**\r\n * Check for a source extension to compose element correctly: video tag for mp4, img — for others\r\n */\r\n const tag = /\\.mp4$/.test(url) ? 'VIDEO' : 'IMG';\r\n\r\n const attributes: { [key: string]: string | boolean } = {\r\n src: url,\r\n };\r\n\r\n /**\r\n * We use eventName variable because IMG and VIDEO tags have different event to be called on source load\r\n * - IMG: load\r\n * - VIDEO: loadeddata\r\n */\r\n let eventName = 'load';\r\n\r\n /**\r\n * Update attributes and eventName if source is a mp4 video\r\n */\r\n if (tag === 'VIDEO') {\r\n /**\r\n * Add attributes for playing muted mp4 as a gif\r\n */\r\n attributes.autoplay = true;\r\n attributes.loop = true;\r\n attributes.muted = true;\r\n attributes.playsinline = true;\r\n\r\n /**\r\n * Change event to be listened\r\n */\r\n eventName = 'loadeddata';\r\n }\r\n\r\n /**\r\n * Compose tag with defined attributes\r\n */\r\n this.nodes.imageEl = make(tag, this.CSS.imageEl, attributes);\r\n\r\n /**\r\n * Add load event listener\r\n */\r\n this.nodes.imageEl.addEventListener(eventName, () => {\r\n this.toggleStatus(UiState.Filled);\r\n\r\n /**\r\n * Preloader does not exists on first rendering with presaved data\r\n */\r\n if (this.nodes.imagePreloader !== undefined) {\r\n this.nodes.imagePreloader.style.backgroundImage = '';\r\n }\r\n });\r\n\r\n this.nodes.imageContainer.appendChild(this.nodes.imageEl);\r\n }\r\n\r\n /**\r\n * Shows caption input\r\n * @param text - caption content text\r\n */\r\n public fillCaption(text: string): void {\r\n if (this.nodes.caption !== undefined) {\r\n this.nodes.caption.innerHTML = text;\r\n }\r\n }\r\n\r\n /**\r\n * Changes UI status\r\n * @param status - see {@link Ui.status} constants\r\n */\r\n public toggleStatus(status: UiState): void {\r\n for (const statusType in UiState) {\r\n if (Object.prototype.hasOwnProperty.call(UiState, statusType)) {\r\n const state = UiState[statusType as keyof typeof UiState];\r\n\r\n this.nodes.wrapper.classList.toggle(`${this.CSS.wrapper}--${state}`, state === status);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * CSS classes\r\n */\r\n private get CSS(): Record<string, string> {\r\n return {\r\n baseClass: this.api.styles.block,\r\n loading: this.api.styles.loader,\r\n input: this.api.styles.input,\r\n button: this.api.styles.button,\r\n\r\n /**\r\n * Tool's classes\r\n */\r\n wrapper: 'image-tool',\r\n imageContainer: 'image-tool__image',\r\n imagePreloader: 'image-tool__image-preloader',\r\n imageEl: 'image-tool__image-picture',\r\n caption: 'image-tool__caption',\r\n };\r\n };\r\n\r\n /**\r\n * Creates upload-file button\r\n */\r\n private createFileButton(): HTMLElement {\r\n const button = make('div', [this.CSS.button]);\r\n\r\n button.innerHTML = this.config.buttonContent ?? `${IconPicture} ${this.api.i18n.t('Select an Image')}`;\r\n\r\n button.addEventListener('click', () => {\r\n this.onSelectFile();\r\n });\r\n\r\n return button;\r\n }\r\n}\r\n","\r\nimport isPromise from './utils/isPromise';\r\nimport type { IUploadResponseFormat, UploadOptions } from './types/types';\r\nimport type { UploadResponseFormat, ImageConfig } from './types/types';\r\nimport axios, { AxiosInstance } from \"axios\";\r\nimport { selectFiles } from './utils/index';\r\n/**\r\n * Params interface for Uploader constructor\r\n */\r\ninterface UploaderParams {\r\n /**\r\n * Configuration for the uploader\r\n */\r\n config: ImageConfig;\r\n\r\n /**\r\n * Handles the upload response.\r\n * @param {UploadResponseFormat} response - Response format expected from the backend on file uploading.\r\n * @returns {void}\r\n */\r\n onUpload: (response: UploadResponseFormat) => void;\r\n\r\n /**\r\n *\r\n * @param error : error type\r\n * @returns void\r\n */\r\n onError: (error: string) => void;\r\n}\r\n\r\n/**\r\n * Module for file uploading. Handle 3 scenarios:\r\n * 1. Select file from device and upload\r\n * 2. Upload by pasting URL\r\n * 3. Upload by pasting file from Clipboard or by Drag'n'Drop\r\n */\r\nexport default class Uploader {\r\n private config: ImageConfig;\r\n private onUpload: (response: UploadResponseFormat) => void;\r\n private onError: (error: string) => void;\r\n /**\r\n * @param params - uploader module params\r\n * @param params.config - image tool config\r\n * @param params.onUpload - one callback for all uploading (file, url, d-n-d, pasting)\r\n * @param params.onError - callback for uploading errors\r\n */\r\n constructor({ config, onUpload, onError }: UploaderParams) {\r\n this.config = config;\r\n this.onUpload = onUpload;\r\n this.onError = onError;\r\n }\r\n\r\n /**\r\n * Handle clicks on the upload file button\r\n * Fires ajax.transport()\r\n * @param onPreview - callback fired when preview is ready\r\n */\r\n public async uploadSelectedFile({ onPreview, noSelectedFile }: UploadOptions) {\r\n\r\n const preparePreview = function (file: File): void {\r\n const reader = new FileReader();\r\n\r\n reader.readAsDataURL(file);\r\n reader.onload = (e) => {\r\n onPreview((e.target as FileReader).result as string);\r\n };\r\n };\r\n\r\n /**\r\n * Custom uploading\r\n * or default uploading\r\n */\r\n\r\n let cdn: string = \"\";\r\n let objectKey: string = \"\";\r\n\r\n\r\n\r\n //选获取上传文件的地址\r\n const files = await selectFiles({ accept: this.config.types ?? 'image/*' });\r\n\r\n if (files && files.length > 0) {\r\n preparePreview(files[0]);\r\n } else {\r\n noSelectedFile();\r\n return\r\n }\r\n const file = files[0];\r\n const fileTypes = this.config.types.split(\",\");\r\n let suffixIndex = file.name.lastIndexOf(\".\");\r\n let suffix = file.name.slice(suffixIndex);\r\n\r\n if (!fileTypes.includes(suffix.toLowerCase())) {\r\n this.onError(\"文件类型不支持\");\r\n return;\r\n }\r\n\r\n let headers: Record<string, string> = {};\r\n if (this.config.userStore) {\r\n const token = this.config.userStore.token;\r\n const tokenName = this.config.userStore.tokenName;\r\n const tokenPrefix = this.config.userStore.tokenPrefix;\r\n if (token && tokenName) {\r\n headers[tokenName] = tokenPrefix + \" \" + token\r\n }\r\n }\r\n const axiosInstance: AxiosInstance = axios.create({\r\n timeout: 1800000,\r\n headers: headers,\r\n });\r\n headers[\"Content-Type\"] = \"application/json\";\r\n\r\n const uploadBodyRes = await axiosInstance.post(this.config.endpoints.byFile!, {\r\n \"fileName\": file.name,\r\n \"contentType\": file.type\r\n })\r\n if (uploadBodyRes.status !== 200) {\r\n this.onError(uploadBodyRes.statusText);\r\n return;\r\n }\r\n const uploadRes = uploadBodyRes.data;\r\n if (!uploadRes.success) {\r\n this.onError(uploadRes.message!);\r\n return;\r\n }\r\n console.log(uploadRes);\r\n cdn = uploadRes.data.cdn;\r\n objectKey = uploadRes.data.objectKey;\r\n\r\n\r\n headers[\"Content-Type\"] = file.type;\r\n\r\n let upload = axiosInstance.put(uploadRes.data.presignedUrl, file);\r\n\r\n\r\n\r\n\r\n upload.then((response) => {\r\n if (response.status === 200) {\r\n response = {\r\n success: 1,\r\n file: { url: cdn + objectKey }\r\n }\r\n }\r\n this.onUpload(response);\r\n }).catch((error: string) => {\r\n this.onError(error);\r\n });\r\n }\r\n\r\n /**\r\n * Handle clicks on the upload file button\r\n * Fires ajax.post()\r\n * @param url - image source url\r\n */\r\n public uploadByUrl(url: string): void {\r\n let upload;\r\n let headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\r\n if (this.config.userStore) {\r\n const token = this.config.userStore.token;\r\n const tokenName = this.config.userStore.tokenName;\r\n const tokenPrefix = this.config.userStore.tokenPrefix;\r\n if (token && tokenName) {\r\n headers[tokenName] = tokenPrefix + \" \" + token\r\n }\r\n }\r\n const axiosInstance: AxiosInstance = axios.create({\r\n timeout: 1800000,\r\n headers: headers,\r\n });\r\n upload = axiosInstance.post(this.config.endpoints.byUrl!, {\r\n \"url\": url,\r\n \"accept\": \".jpg,.jpeg,.gif,.png,.webp\"\r\n })\r\n\r\n\r\n\r\n\r\n upload.then((response) => {\r\n \r\n if(response.status !== 200||response.data.success===false){\r\n this.onError(response.data.message!);\r\n return;\r\n }\r\n \r\n let cdn = response.data.data.cdn;\r\n let objectKey = response.data.data.objectKey;\r\n\r\n let res = {\r\n success: 1,\r\n file: { url: cdn + objectKey }\r\n };\r\n this.onUpload(res);\r\n }).catch((error: string) => {\r\n this.onError(error);\r\n });\r\n\r\n }\r\n\r\n /**\r\n * Handle clicks on the upload file button\r\n * Fires ajax.post()\r\n * @param file - file pasted by drag-n-drop\r\n * @param onPreview - file pasted by drag-n-drop\r\n */\r\n public async uploadByFile(file: Blob, { onPreview }: UploadOptions) {\r\n\r\n\r\n const fileTypes = this.config.types.split(\",\");\r\n\r\n let suffixIndex = file.name.lastIndexOf(\".\");\r\n let suffix = file.name.slice(suffixIndex);\r\n\r\n if (!fileTypes.includes(suffix.toLowerCase())) {\r\n this.onError(\"文件类型不支持\");\r\n return;\r\n }\r\n\r\n\r\n\r\n let headers: Record<string, string> = {};\r\n if (this.config.userStore) {\r\n const token = this.config.userStore.token;\r\n const tokenName = this.config.userStore.tokenName;\r\n const tokenPrefix = this.config.userStore.tokenPrefix;\r\n if (token && tokenName) {\r\n headers[tokenName] = tokenPrefix + \" \" + token\r\n }\r\n }\r\n const axiosInstance: AxiosInstance = axios.create({\r\n timeout: 1800000,\r\n headers: headers,\r\n });\r\n headers[\"Content-Type\"] = \"application/json\";\r\n\r\n const uploadBodyRes = await axiosInstance.post(this.config.endpoints.byFile!, {\r\n \"fileName\": file.name,\r\n \"contentType\": file.type\r\n })\r\n if (uploadBodyRes.status !== 200) {\r\n this.onError(uploadBodyRes.statusText);\r\n return;\r\n }\r\n const uploadRes = uploadBodyRes.data;\r\n if (!uploadRes.success) {\r\n this.onError(uploadRes.message!);\r\n return;\r\n }\r\n console.log(uploadRes);\r\n let cdn = uploadRes.data.cdn;\r\n let objectKey = uploadRes.data.objectKey;\r\n\r\n\r\n headers[\"Content-Type\"] = file.type;\r\n let upload = axiosInstance.put(uploadRes.data.presignedUrl, file);\r\n upload.then((response) => {\r\n if (response.status === 200) {\r\n response = {\r\n success: 1,\r\n file: { url: cdn + objectKey }\r\n }\r\n }\r\n this.onUpload(response);\r\n }).catch((error: string) => {\r\n this.onError(error);\r\n });\r\n }\r\n}\r\n"," interface IConfig {\r\n multiple?: boolean;\r\n accept?: string;\r\n }\r\nexport function selectFiles(config = {} as IConfig): Promise<File[]> {\r\n let fileCancle = true;\r\n return new Promise((resolve, reject) => {\r\n /**\r\n * Create a new INPUT element\r\n * @type {HTMLElement}\r\n */\r\n let inputElement = document.createElement('INPUT');\r\n\r\n /**\r\n * Set a 'FILE' type for this input element\r\n * @type {string}\r\n */\r\n inputElement.type = 'file';\r\n\r\n if (config.multiple) {\r\n inputElement.setAttribute('multiple', 'multiple');\r\n }\r\n\r\n if (config.accept) {\r\n inputElement.setAttribute('accept', config.accept);\r\n }\r\n\r\n /**\r\n * Do not show element\r\n */\r\n inputElement.style.display = 'none';\r\n\r\n /**\r\n * Append element to the body\r\n * Fix using module on mobile devices\r\n */\r\n document.body.appendChild(inputElement);\r\n\r\n /**\r\n * Add onchange listener for «choose file» pop-up\r\n */\r\n inputElement.addEventListener('change', event => {\r\n console.log(\"选中文件\")\r\n fileCancle = false;\r\n /**\r\n * Get files from input field\r\n */\r\n const files = event.target.files;\r\n\r\n /**\r\n * Return ready to be uploaded files array\r\n */\r\n resolve(files);\r\n\r\n /**\r\n * Remove element from a DOM\r\n */\r\n document.body.removeChild(inputElement);\r\n }, false);\r\n window.addEventListener(\"focus\", () => { \r\n setTimeout(() => {\r\n if (fileCancle) {\r\n console.log(\"取消选择文件\")\r\n resolve([]);\r\n }\r\n }, 1000)\r\n },{once: true})\r\n /**\r\n * Fire click event on «input file» field\r\n */\r\n inputElement.click();\r\n });\r\n };","/**\r\n * Image Tool for the Editor.js\r\n * @author CodeX <team@codex.so>\r\n * @license MIT\r\n * @see {@link https://github.com/editor-js/image}\r\n *\r\n * To developers.\r\n * To simplify Tool structure, we split it to 4 parts:\r\n * 1) index.ts — main Tool's interface, public API and methods for working with data\r\n * 2) uploader.ts — module that has methods for sending files via AJAX: from device, by URL or File pasting\r\n * 3) ui.ts — module for UI manipulations: render, showing preloader, etc\r\n *\r\n * For debug purposes there is a testing server\r\n * that can save uploaded files and return a Response {@link UploadResponseFormat}\r\n *\r\n * $ node dev/server.js\r\n *\r\n * It will expose 8008 port, so you can pass http://localhost:8008 with the Tools config:\r\n *\r\n * image: {\r\n * class: ImageTool,\r\n * config: {\r\n * endpoints: {\r\n * byFile: 'http://localhost:8008/uploadFile',\r\n * byUrl: 'http://localhost:8008/fetchUrl',\r\n * }\r\n * },\r\n * },\r\n */\r\n\r\nimport type { TunesMenuConfig } from '@ebl-vue/editorjs/types/tools';\r\nimport type { API, ToolboxConfig, PasteConfig, BlockToolConstructorOptions, BlockTool, BlockAPI, PasteEvent, PatternPasteEventDetail, FilePasteEventDetail } from '@editorjs/editorjs';\r\nimport './index.css';\r\n\r\nimport Ui from './ui';\r\nimport Uploader from './uploader';\r\n\r\nimport { IconAddBorder, IconStretch, IconAddBackground, IconPicture, IconText } from '../../icons';\r\nimport type { ActionConfig, UploadResponseFormat, ImageToolData, ImageConfig, HTMLPasteEventDetailExtended, ImageSetterParam, FeaturesConfig } from './types/types';\r\n\r\ntype ImageToolConstructorOptions = BlockToolConstructorOptions<ImageToolData, ImageConfig>;\r\n\r\n/**\r\n * Implementation of ImageTool class\r\n */\r\nexport default class ImageTool implements BlockTool {\r\n /**\r\n * Editor.js API instance\r\n */\r\n private api: API;\r\n\r\n /**\r\n * Current Block API instance\r\n */\r\n private block: BlockAPI;\r\n\r\n /**\r\n * Configuration for the ImageTool\r\n */\r\n private config: ImageConfig;\r\n\r\n /**\r\n * Uploader module instance\r\n */\r\n private uploader: any;\r\n\r\n /**\r\n * UI module instance\r\n */\r\n private ui: Ui;\r\n\r\n /**\r\n * Stores current block data internally\r\n */\r\n private _data: ImageToolData;\r\n\r\n private userStore:any;\r\n\r\n\r\n /**\r\n * Caption enabled state\r\n * Null when user has not toggled the caption tune\r\n * True when user has toggled the caption tune\r\n * False when user has toggled the caption tune\r\n */\r\n private isCaptionEnabled: boolean | null = null;\r\n\r\n /**\r\n * @param tool - tool properties got from editor.js\r\n * @param tool.data - previously saved data\r\n * @param tool.config - user config for Tool\r\n * @param tool.api - Editor.js API\r\n * @param tool.readOnly - read-only mode flag\r\n * @param tool.block - current Block API\r\n */\r\n constructor({ data, config, api, readOnly, block }: ImageToolConstructorOptions) {\r\n this.api = api;\r\n this.block = block;\r\n this.userStore=config?.userStore;\r\n \r\n /**\r\n * Tool's initial config\r\n */\r\n this.config = {\r\n endpoints: config.endpoints,\r\n additionalRequestData: config.additionalRequestData,\r\n additionalRequestHeaders: config.additionalRequestHeaders,\r\n field: config.field,\r\n types: config.types,\r\n captionPlaceholder: this.api.i18n.t(config.captionPlaceholder ?? 'Caption'),\r\n buttonContent: config.buttonContent,\r\n uploader: config.uploader,\r\n actions: config.actions,\r\n features: config.features || {},\r\n userStore: config.userStore,\r\n };\r\n \r\n\r\n /**\r\n * Module for file uploading\r\n */\r\n this.uploader = new Uploader({\r\n config: this.config,\r\n onUpload: (response: UploadResponseFormat) => this.onUpload(response),\r\n onError: (error: string) => this.uploadingFailed(error),\r\n });\r\n\r\n /**\r\n * Module for working with UI\r\n */\r\n this.ui = new Ui({\r\n api,\r\n config: this.config,\r\n onSelectFile: () => {\r\n this.uploader.uploadSelectedFile({\r\n onPreview: (src: string) => {\r\n this.ui.showPreloader(src);\r\n },\r\n noSelectedFile:()=>{\r\n this.noSelectedFile();\r\n }\r\n });\r\n },\r\n readOnly,\r\n });\r\n\r\n /**\r\n * Set saved state\r\n */\r\n this._data = {\r\n caption: '',\r\n withBorder: false,\r\n withBackground: false,\r\n stretched: false,\r\n file: {\r\n url: '',\r\n },\r\n };\r\n this.data = data;\r\n }\r\n\r\n private noSelectedFile(): void {\r\n this.api.blocks.delete(this.api.blocks.getCurrentBlockIndex());\r\n }\r\n private deleteCurrentBlock() {\r\n this.api.blocks.delete(this.api.blocks.getCurrentBlockIndex());\r\n }\r\n /**\r\n * Notify core that read-only mode is supported\r\n */\r\n public static get isReadOnlySupported(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Get Tool toolbox settings\r\n * icon - Tool icon's SVG\r\n * title - title to show in toolbox\r\n */\r\n public static get toolbox(): ToolboxConfig {\r\n return {\r\n icon: IconPicture,\r\n title: 'Image',\r\n };\r\n }\r\n\r\n /**\r\n * Available image tools\r\n */\r\n public static get tunes(): Array<ActionConfig> {\r\n return [\r\n {\r\n name: 'withBorder',\r\n icon: IconAddBorder,\r\n title: 'With border',\r\n toggle: true,\r\n },\r\n {\r\n name: 'stretched',\r\n icon: IconStretch,\r\n title: 'Stretch image',\r\n toggle: true,\r\n },\r\n {\r\n name: 'withBackground',\r\n icon: IconAddBackground,\r\n title: 'With background',\r\n toggle: true,\r\n },\r\n ];\r\n }\r\n\r\n /**\r\n * Renders Block content\r\n */\r\n public render(): HTMLDivElement {\r\n if (this.config.features?.caption === true || this.config.features?.caption === undefined || (this.config.features?.caption === 'optional' && this.data.caption)) {\r\n this.isCaptionEnabled = true;\r\n this.ui.applyTune('caption', true);\r\n }\r\n\r\n return this.ui.render() as HTMLDivElement;\r\n }\r\n\r\n /**\r\n * Validate data: check if Image exists\r\n * @param savedData — data received after saving\r\n * @returns false if saved data is not correct, otherwise true\r\n */\r\n public validate(savedData: ImageToolData): boolean {\r\n return !!savedData.file.url;\r\n }\r\n\r\n /**\r\n * Return Block data\r\n */\r\n public save(): ImageToolData {\r\n const caption = this.ui.nodes.caption;\r\n\r\n this._data.caption = caption.innerHTML;\r\n\r\n return this.data;\r\n }\r\n\r\n /**\r\n * Returns configuration for block tunes: add background, add border, stretch image\r\n * @returns TunesMenuConfig\r\n */\r\n public renderSettings(): TunesMenuConfig {\r\n // Merge default tunes with the ones that might be added by user\r\n // @see https://github.com/editor-js/image/pull/49\r\n const tunes = ImageTool.tunes.concat(this.config.actions || []);\r\n const featureTuneMap: Record<string, string> = {\r\n border: 'withBorder',\r\n background: 'withBackground',\r\n stretch: 'stretched',\r\n caption: 'caption',\r\n };\r\n\r\n if (this.config.features?.caption === 'optional') {\r\n tunes.push({\r\n name: 'caption',\r\n icon: IconText,\r\n title: 'With caption',\r\n toggle: true,\r\n });\r\n }\r\n\r\n const availableTunes = tunes.filter((tune) => {\r\n const featureKey = Object.keys(featureTuneMap).find(key => featureTuneMap[key] === tune.name);\r\n\r\n if (featureKey === 'caption') {\r\n return this.config.features?.caption !== false;\r\n }\r\n\r\n return featureKey == null || this.config.features?.[featureKey as keyof FeaturesConfig] !== false;\r\n });\r\n\r\n /**\r\n * Check if the tune is active\r\n * @param tune - tune to check\r\n */\r\n const isActive = (tune: ActionConfig): boolean => {\r\n let currentState = this.data[tune.name as keyof ImageToolData] as boolean;\r\n\r\n if (tune.name === 'caption') {\r\n currentState = this.isCaptionEnabled ?? currentState;\r\n }\r\n\r\n return currentState;\r\n };\r\n\r\n return availableTunes.map(tune => ({\r\n icon: tune.icon,\r\n label: this.api.i18n.t(tune.title),\r\n name: tune.name,\r\n toggle: tune.toggle,\r\n isActive: isActive(tune),\r\n onActivate: () => {\r\n /** If it'a user defined tune, execute it's callback stored in action property */\r\n if (typeof tune.action === 'function') {\r\n tune.action(tune.name);\r\n\r\n return;\r\n }\r\n let newState = !isActive(tune);\r\n\r\n /**\r\n * For the caption tune, we can't rely on the this._data\r\n * because it can be manualy toggled by user\r\n */\r\n if (tune.name === 'caption') {\r\n this.isCaptionEnabled = !(this.isCaptionEnabled ?? false);\r\n newState = this.isCaptionEnabled;\r\n }\r\n\r\n this.tuneToggled(tune.name as keyof ImageToolData, newState);\r\n },\r\n }));\r\n }\r\n\r\n /**\r\n * Fires after clicks on the Toolbox Image Icon\r\n * Initiates click on the Select File button\r\n */\r\n public appendCallback(): void {\r\n this.ui.nodes.fileButton.click();\r\n }\r\n\r\n /**\r\n * Specify paste substitutes\r\n * @see {@link https://github.com/codex-team/editor.js/blob/master/docs/tools.md#paste-handling}\r\n */\r\n public static get pasteConfig(): PasteConfig {\r\n return {\r\n /**\r\n * Paste HTML into Editor\r\n */\r\n tags: [\r\n {\r\n img: { src: true },\r\n },\r\n ],\r\n /**\r\n * Paste URL of image into the Editor\r\n */\r\n // patterns: {\r\n // image: /https?:\\/\\/\\S+\\.(gif|jpe?g|png|webp)(\\?[a-z0-9=]*)?$/i,\r\n // },\r\n\r\n /**\r\n * Drag n drop file from into the Editor\r\n */\r\n files: {\r\n mimeTypes: ['image/*'],\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Specify paste handlers\r\n * @see {@link https://github.com/codex-team/editor.js/blob/master/docs/tools.md#paste-handling}\r\n * @param event - editor.js custom paste event\r\n * {@link https://github.com/codex-team/editor.js/blob/master/types/tools/paste-events.d.ts}\r\n */\r\n public async onPaste(event: PasteEvent): Promise<void> {\r\n switch (event.type) {\r\n case 'tag': {\r\n const image = (event.detail as HTMLPasteEventDetailExtended).data;\r\n\r\n /** Images from PDF */\r\n if (/^blob:/.test(image.src)) {\r\n const response = await fetch(image.src);\r\n\r\n const file = await response.blob();\r\n\r\n this.uploadFile(file);\r\n break;\r\n }\r\n\r\n this.uploadUrl(image.src);\r\n break;\r\n }\r\n // case 'pattern': {\r\n // const url = (event.detail as PatternPasteEventDetail).data;\r\n\r\n // this.uploadUrl(url);\r\n // break;\r\n // }\r\n case 'file': {\r\n const file = (event.detail as FilePasteEventDetail).file;\r\n\r\n this.uploadFile(file);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Private methods\r\n */\r\n\r\n /**\r\n * Stores all Tool's data\r\n * @param data - data in Image Tool format\r\n */\r\n private set data(data: ImageToolData) {\r\n this.image = data.file;\r\n\r\n this._data.caption = data.caption || '';\r\n this.ui.fillCaption(this._data.caption);\r\n\r\n ImageTool.tunes.forEach(({ name: tune }) => {\r\n const value = typeof data[tune as keyof ImageToolData] !== 'undefined' ? data[tune as keyof ImageToolData] === true || data[tune as keyof ImageToolData] === 'true' : false;\r\n\r\n this.setTune(tune as keyof ImageToolData, value);\r\n });\r\n\r\n if (data.caption) {\r\n this.setTune('caption', true);\r\n } else if (this.config.features?.caption === true) {\r\n this.setTune('caption', true);\r\n }\r\n }\r\n\r\n /**\r\n * Return Tool data\r\n */\r\n private get data(): ImageToolData {\r\n return this._data;\r\n }\r\n\r\n /**\r\n * Set new image file\r\n * @param file - uploaded file data\r\n */\r\n private set image(file: ImageSetterParam | undefined) {\r\n this._data.file = file || { url: '' };\r\n\r\n if (file && file.url) {\r\n this.ui.fillImage(file.url);\r\n }\r\n }\r\n\r\n /**\r\n * File uploading callback\r\n * @param response - uploading server response\r\n */\r\n private onUpload(response: UploadResponseFormat): void {\r\n if (response.success && Boolean(response.file)) {\r\n this.image = response.file;\r\n } else {\r\n this.uploadingFailed('incorrect response: ' + JSON.stringify(response));\r\n }\r\n }\r\n\r\n /**\r\n * Handle uploader errors\r\n * @param errorText - uploading error info\r\n */\r\n private uploadingFailed(errorText: string): void {\r\n console.log('Image Tool: uploading failed because of', errorText);\r\n let errorMessage = this.api.i18n.t('Couldn’t upload image. Please try another.');\r\n if (errorText) {\r\n errorMessage = this.api.i18n.t(errorText);\r\n }\r\n this.api.notifier.show({\r\n message: errorMessage,\r\n style: 'error',\r\n });\r\n this.ui.hidePreloader();\r\n this.deleteCurrentBlock();\r\n }\r\n\r\n /**\r\n * Callback fired when Block Tune is activated\r\n * @param tuneName - tune that has been clicked\r\n * @param state - new state\r\n */\r\n private tuneToggled(tuneName: keyof ImageToolData, state: boolean): void {\r\n if (tuneName === 'caption') {\r\n this.ui.applyTune(tuneName, state);\r\n\r\n if (state == false) {\r\n this._data.caption = '';\r\n this.ui.fillCaption('');\r\n }\r\n } else {\r\n /**\r\n * Inverse tune state\r\n */\r\n this.setTune(tuneName, state);\r\n }\r\n }\r\n\r\n /**\r\n * Set one tune\r\n * @param tuneName - {@link Tunes.tunes}\r\n * @param value - tune state\r\n */\r\n private setTune(tuneName: keyof ImageToolData, value: boolean): void {\r\n (this._data[tuneName] as boolean) = value;\r\n\r\n this.ui.applyTune(tuneName, value);\r\n if (tuneName === 'stretched') {\r\n /**\r\n * Wait until the API is ready\r\n */\r\n Promise.resolve().then(() => {\r\n this.block.stretched = value;\r\n })\r\n .catch((err) => {\r\n console.error(err);\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Show preloader and upload image file\r\n * @param file - file that is currently uploading (from paste)\r\n */\r\n private uploadFile(file: Blob): void {\r\n this.uploader.uploadByFile(file, {\r\n onPreview: (src: string) => {\r\n this.ui.showPreloader(src);\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Show preloader and upload image by target url\r\n * @param url - url pasted\r\n */\r\n private uploadUrl(url: string): void {\r\n this.ui.showPreloader(url);\r\n this.uploader.uploadByUrl(url);\r\n }\r\n}\r\n","\r\n//import Cropper from 'cropperjs';\r\n//import 'cropperjs/dist/cropper.css';\r\nimport './index.css';\r\nimport type { BlockTune, API, BlockAPI } from '@ebl-vue/editorjs/types'\r\n\r\n\r\nexport interface TuneSetting {\r\n name: string;\r\n icon: string;\r\n label: string;\r\n group: string;\r\n}\r\n\r\nexport interface ImageToolTuneData {\r\n floatLeft: boolean;\r\n floatRight: boolean;\r\n center: boolean;\r\n sizeSmall: boolean;\r\n sizeMiddle: boolean;\r\n sizeLarge: boolean;\r\n resize: boolean;\r\n resizeSize: number;\r\n crop: boolean;\r\n cropperFrameHeight: number;\r\n cropperFrameWidth: number;\r\n cropperFrameLeft: number;\r\n cropperFrameTop: number;\r\n cropperImageHeight: number;\r\n cropperImageWidth: number;\r\n cropperInterface?: any//Cropper;\r\n}\r\n\r\nexport interface ImageToolTuneConfig {\r\n resize: boolean;\r\n crop: boolean;\r\n}\r\n\r\nexport interface CustomStyles {\r\n settingsButton: string;\r\n settingsButtonActive: string;\r\n settingsButtonModifier?: string;\r\n settingsButtonModifierActive?: string;\r\n}\r\n\r\nexport type ImageToolTuneConstructor = {\r\n api: API;\r\n data: Partial<ImageToolTuneData>;\r\n config?: ImageToolTuneConfig;\r\n block: BlockAPI;\r\n};\r\n\r\nexport default class ImageToolTune implements BlockTune {\r\n private settings: TuneSetting[];\r\n private api: API;\r\n private block: BlockAPI;\r\n private data: ImageToolTuneData;\r\n private wrapper: HTMLElement | undefined;\r\n private buttons: HTMLElement[];\r\n private styles: CustomStyles;\r\n\r\n constructor({ api, data, config, block }: ImageToolTuneConstructor) {\r\n this.settings = [\r\n // {\r\n // name: 'resize',\r\n // icon: '<svg stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" viewBox=\"0 0 512 512\" height=\"1em\" width=\"1em\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M29 30l1 90h36V66h26V30H29zm99 0v36h72V30h-72zm108 0v36h72V30h-72zm108 0v36h72V30h-72zm102 0v78h36V30h-36zm-206 80v36h100.543l-118 118H30v218h218V289.457l118-118V272h36V110H240zm206 34v72h36v-72h-36zM30 156v72h36v-72H30zm416 96v72h36v-72h-36zm0 108v72h36v-72h-36zm-166 86v36h72v-36h-72zm108 0v36h72v-36h-72z\"></path></svg>',\r\n // label: '',\r\n // group: 'size',\r\n // },\r\n // {\r\n // name: 'crop',\r\n // icon: '<svg stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" viewBox=\"0 0 24 24\" height=\"1em\" width=\"1em\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M21 15h2v2h-2v-2zm0-4h2v2h-2v-2zm2 8h-2v2c1 0 2-1 2-2zM13 3h2v2h-2V3zm8 4h2v2h-2V7zm0-4v2h2c0-1-1-2-2-2zM1 7h2v2H1V7zm16-4h2v2h-2V3zm0 16h2v2h-2v-2zM3 3C2 3 1 4 1 5h2V3zm6 0h2v2H9V3zM5 3h2v2H5V3zm-4 8v8c0 1.1.9 2 2 2h12V11H1zm2 8l2.5-3.21 1.79 2.15 2.5-3.22L13 19H3z\"></path></svg>',\r\n // label: '',\r\n // group: 'size',\r\n // },\r\n ];\r\n\r\n this.api = api;\r\n this.block = block;\r\n this.data = {\r\n floatLeft: data?.floatLeft ?? false,\r\n floatRight: data?.floatRight ?? false,\r\n center: data?.center ?? false,\r\n sizeSmall: data?.sizeSmall ?? false,\r\n sizeMiddle: data?.sizeMiddle ?? false,\r\n sizeLarge: data?.sizeLarge ?? false,\r\n resize: data?.resize ?? config?.resize ?? false,\r\n resizeSize: data?.resizeSize ?? 0,\r\n crop: data?.crop ?? config?.crop ?? false,\r\n cropperFrameHeight: data?.cropperFrameHeight ?? 0,\r\n cropperFrameWidth: data?.cropperFrameWidth ?? 0,\r\n cropperFrameLeft: data?.cropperFrameLeft ?? 0,\r\n cropperFrameTop: data?.cropperFrameTop ?? 0,\r\n cropperImageHeight: data?.cropperImageHeight ?? 0,\r\n cropperImageWidth: data?.cropperImageWidth ?? 0,\r\n cropperInterface: undefined,\r\n };\r\n this.wrapper = undefined;\r\n this.buttons = [];\r\n this.styles = {\r\n settingsButton: 'cdx-settings-button',\r\n settingsButtonActive: 'cdx-settings-button--active',\r\n settingsButtonModifier: '',\r\n settingsButtonModifierActive: '',\r\n };\r\n }\r\n\r\n static get isTune(): boolean {\r\n return true;\r\n }\r\n\r\n static get sanitize(): Record<string, object> {\r\n return {\r\n floatLeft: {},\r\n floatRight: {},\r\n center: {},\r\n sizeSmall: {},\r\n sizeMiddle: {},\r\n sizeLarge: {},\r\n resize: {},\r\n resizeSize: {},\r\n crop: {},\r\n cropperFrameHeight: {},\r\n cropperFrameWidth: {},\r\n cropperFrameLeft: {},\r\n cropperFrameTop: {},\r\n cropperImageHeight: {},\r\n cropperImageWidth: {},\r\n cropperInterface: {},\r\n };\r\n }\r\n\r\n /**\r\n * CSS classes\r\n * @return {object}\r\n * @constructor\r\n * @property {string} CSS.wrapper - wrapper for buttons\r\n * @property {string} CSS.button - button\r\n * @property {string} CSS.buttonActive - active button\r\n * @property {string} CSS.buttonModifier - button with modifier\r\n * @property {string} CSS.buttonModifierActive - active button with modifier\r\n */\r\n get CSS(): Record<string, string> {\r\n return {\r\n wrapper: 'cdx-image-tool-tune',\r\n button: this.styles.settingsButton,\r\n buttonActive: this.styles.settingsButtonActive,\r\n buttonModifier: this.styles.settingsButtonModifier || '',\r\n buttonModifierActive: this.styles.settingsButtonModifierActive || '',\r\n isFloatLeft: 'cdx-image-tool-tune--floatLeft',\r\n isFloatRight: 'cdx-image-tool-tune--floatRight',\r\n isCenter: 'cdx-image-tool-tune--center',\r\n isSizeSmall: 'cdx-image-tool-tune--sizeSmall',\r\n isSizeMiddle: 'cdx-image-tool-tune--sizeMiddle',\r\n isSizeLarge: 'cdx-image-tool-tune--sizeLarge',\r\n isResize: 'cdx-image-tool-tune--resize',\r\n isCrop: 'cdx-image-tool-tune--crop',\r\n };\r\n }\r\n\r\n /**\r\n *\r\n * @return {HTMLElement}\r\n * @public\r\n * @readonly\r\n * @property {HTMLElement} wrapper - tune buttons wrapper\r\n */\r\n get view(): HTMLElement {\r\n if (!this.wrapper) {\r\n this.wrapper = this.createView();\r\n }\r\n\r\n return this.wrapper;\r\n }\r\n\r\n /**\r\n * Clicks to one of the tunes\r\n * @param {MouseEvent} e - click\r\n * @param {HTMLElement} tune - clicked tune button\r\n * @private\r\n * @return {void}\r\n * */\r\n tuneClicked(e: MouseEvent, tune: HTMLElement): void {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n const tuneName = tune.dataset.tune || '';\r\n const tuneGroup = this.settings.find(t => t.name === tuneName)?.group;\r\n\r\n this.buttons.forEach(button => {\r\n //if is the same group\r\n if (\r\n this.settings.find(t => t.name === button.dataset.tune)?.group ===\r\n tuneGroup\r\n ) {\r\n if (button !== tune) {\r\n button.classList.remove(this.CSS.buttonActive);\r\n }\r\n }\r\n });\r\n\r\n tune.classList.toggle(this.CSS.buttonActive);\r\n this.setTune(tuneName);\r\n }\r\n\r\n /**\r\n * Styles the image with a tune\r\n * @param {string} tune - tune name\r\n * @private\r\n * @return {void}\r\n * */\r\n setTune(tune: string): void {\r\n switch (tune) {\r\n case 'floatLeft':\r\n this.data.floatLeft = !this.data.floatLeft;\r\n this.data.floatRight = false;\r\n this.data.center = false;\r\n break;\r\n case 'floatRight':\r\n this.data.floatLeft = false;\r\n this.data.floatRight = !this.data.floatRight;\r\n this.data.center = false;\r\n break;\r\n case 'center':\r\n this.data.center = !this.data.center;\r\n this.data.floatLeft = false;\r\n this.data.floatRight = false;\r\n break;\r\n case 'sizeSmall':\r\n this.data.sizeSmall = !this.data.sizeSmall;\r\n this.data.sizeMiddle = false;\r\n this.data.sizeLarge = false;\r\n this.data.resize = false;\r\n this.data.crop = false;\r\n break;\r\n case 'sizeMiddle':\r\n this.data.sizeSmall = false;\r\n this.data.sizeMiddle = !this.data.sizeMiddle;\r\n this.data.sizeLarge = false;\r\n this.data.resize = false;\r\n this.data.crop = false;\r\n break;\r\n case 'sizeLarge':\r\n this.data.sizeSmall = false;\r\n this.data.sizeMiddle = false;\r\n this.data.sizeLarge = !this.data.sizeLarge;\r\n this.data.resize = false;\r\n this.data.crop = false;\r\n break;\r\n case 'resize':\r\n this.data.sizeSmall = false;\r\n this.data.sizeMiddle = false;\r\n this.data.sizeLarge = false;\r\n this.data.resize = !this.data.resize;\r\n this.data.crop = false;\r\n break;\r\n case 'crop':\r\n this.data.crop = !this.data.crop;\r\n this.data.sizeSmall = false;\r\n this.data.sizeMiddle = false;\r\n this.data.sizeLarge = false;\r\n this.data.resize = false;\r\n this.data.resizeSize = 0;\r\n break;\r\n default:\r\n this.data.floatLeft = false;\r\n this.data.floatRight = false;\r\n this.data.sizeSmall = false;\r\n this.data.sizeMiddle = false;\r\n this.data.sizeLarge = false;\r\n this.data.resize = false;\r\n this.data.crop = false;\r\n break;\r\n }\r\n\r\n if (!this.data.resize) {\r\n this.data.resizeSize = 0;\r\n }\r\n\r\n if (!this.data.crop) {\r\n this.data.cropperFrameHeight = 0;\r\n this.data.cropperFrameWidth = 0;\r\n this.data.cropperFrameLeft = 0;\r\n this.data.cropperFrameTop = 0;\r\n this.data.cropperImageHeight = 0;\r\n this.data.cropperImageWidth = 0;\r\n }\r\n\r\n const blockContent = this.block.holder.querySelector(\r\n '.ce-block__content',\r\n ) as HTMLElement;\r\n this.apply(blockContent);\r\n this.block.dispatchChange();\r\n }\r\n\r\n /**\r\n * Append class to block by tune data\r\n * @param {HTMLElement} blockContent - wrapper for block content\r\n * @public\r\n * @return {void}\r\n * */\r\n apply(blockContent: HTMLElement): void {\r\n if (this.data.floatLeft) {\r\n blockContent.classList.add(this.CSS.isFloatLeft);\r\n } else {\r\n blockContent.classList.remove(this.CSS.isFloatLeft);\r\n }\r\n\r\n if (this.data.floatRight) {\r\n blockContent.classList.add(this.CSS.isFloatRight);\r\n } else {\r\n blockContent.classList.remove(this.CSS.isFloatRight);\r\n }\r\n\r\n if (this.data.center) {\r\n blockContent.classList.add(this.CSS.isCenter);\r\n } else {\r\n blockContent.classList.remove(this.CSS.isCenter);\r\n }\r\n\r\n if (this.data.sizeSmall) {\r\n blockContent.classList.add(this.CSS.isSizeSmall);\r\n } else {\r\n blockContent.classList.remove(this.CSS.isSizeSmall);\r\n }\r\n\r\n if (this.data.sizeMiddle) {\r\n blockContent.classList.add(this.CSS.isSizeMiddle);\r\n } else {\r\n blockContent.classList.remove(this.CSS.isSizeMiddle);\r\n }\r\n\r\n if (this.data.sizeLarge) {\r\n blockContent.classList.add(this.CSS.isSizeLarge);\r\n } else {\r\n blockContent.classList.remove(this.CSS.isSizeLarge);\r\n }\r\n\r\n if (this.data.resize) {\r\n blockContent.classList.add(this.CSS.isResize);\r\n\r\n if (this.data.resizeSize > 0) {\r\n const cdxBlock = blockContent.getElementsByClassName(\r\n 'cdx-block',\r\n )[0] as HTMLElement;\r\n cdxBlock.style.width = this.data.resizeSize + 'px';\r\n }\r\n\r\n this.resize(blockContent);\r\n } else {\r\n blockContent.classList.remove(this.CSS.isResize);\r\n this.unresize(blockContent);\r\n }\r\n\r\n if (this.data.crop) {\r\n blockContent.classList.add(this.CSS.isCrop);\r\n\r\n this.crop(blockContent);\r\n if (this.data.cropperFrameHeight > 0 && this.data.cropperFrameWidth > 0) {\r\n this.applyCrop(blockContent);\r\n }\r\n } else {\r\n blockContent.classList.remove(this.CSS.isCrop);\r\n this.uncrop(blockContent);\r\n }\r\n }\r\n\r\n /**\r\n * Add crop handles to image\r\n * @param {HTMLElement} blockContent - wrapper for block content\r\n * @public\r\n * @return {void}\r\n */\r\n crop(blockContent: HTMLElement): void {\r\n //add append crop button to image-tool__image\r\n //If editor is readOnly, do not add crop button\r\n if (this.api.readOnly.isEnabled) return;\r\n\r\n const image = blockContent.getElementsByClassName(\r\n 'image-tool__image',\r\n )[0] as HTMLElement;\r\n const cropBtn = document.createElement('div');\r\n cropBtn.classList.add('crop-btn', 'btn-crop-action');\r\n cropBtn.innerHTML = this.api.i18n.t('Crop');\r\n\r\n cropBtn.addEventListener('click', () => {\r\n //remove crop button\r\n image.removeChild(cropBtn);\r\n this.appendCrop(blockContent);\r\n });\r\n\r\n image.appendChild(cropBtn);\r\n }\r\n\r\n appendCrop(blockContent: HTMLElement): void {\r\n if (this.api.readOnly.isEnabled) return;\r\n\r\n this.uncrop(blockContent);\r\n const cdxBlock = blockContent.getElementsByClassName(\r\n 'cdx-block',\r\n )[0] as HTMLElement;\r\n const image = cdxBlock.getElementsByTagName('img')[0] as HTMLImageElement;\r\n cdxBlock.classList.add('isCropping');\r\n this.data.cropperInterface = new Cropper(image);\r\n\r\n //append save crop button\r\n const cropSaveBtn = document.createElement('div');\r\n cropSaveBtn.classList.add('crop-save', 'btn-crop-action');\r\n cropSaveBtn.innerHTML = this.api.i18n.t('Apply');\r\n\r\n cropSaveBtn.addEventListener('click', () => {\r\n if (this.data.cropperInterface) {\r\n this.data.cropperFrameHeight =\r\n this.data.cropperInterface.getCropBoxData().height;\r\n this.data.cropperFrameWidth =\r\n this.data.cropperInterface.getCropBoxData().width;\r\n this.data.cropperFrameLeft =\r\n this.data.cropperInterface.getCanvasData().left -\r\n this.data.cropperInterface.getCropBoxData().left;\r\n this.data.cropperFrameTop =\r\n this.data.cropperInterface.getCanvasData().top -\r\n this.data.cropperInterface.getCropBoxData().top;\r\n this.data.cropperImageHeight =\r\n this.data.cropperInterface.getImageData().height;\r\n this.data.cropperImageWidth =\r\n this.data.cropperInterface.getImageData().width;\r\n }\r\n this.applyCrop(blockContent);\r\n });\r\n\r\n const imageToolImage = blockContent.getElementsByClassName(\r\n 'image-tool__image',\r\n )[0] as HTMLElement;\r\n imageToolImage.appendChild(cropSaveBtn);\r\n\r\n //add temporary style to block content so that it comes in front of every other block\r\n blockContent.classList.add('isCropping');\r\n }\r\n\r\n applyCrop(blockContent: HTMLElement): void {\r\n //apply data to image and remove cropper interface and save button, add crop button\r\n const blockEl = blockContent.getElementsByClassName(\r\n 'cdx-block',\r\n )[0] as HTMLElement;\r\n if (blockEl) {\r\n blockEl.style.minWidth = this.data.cropperFrameWidth + 'px';\r\n blockEl.style.maxWidth = this.data.cropperFrameWidth + 'px';\r\n\r\n const image = blockEl.getElementsByTagName('img')[0] as HTMLImageElement;\r\n image.style.width = this.data.cropperImageWidth + 'px';\r\n image.style.height = this.data.cropperImageHeight + 'px';\r\n\r\n const blockImg = blockContent.getElementsByClassName(\r\n 'image-tool__image',\r\n )[0] as HTMLElement;\r\n blockImg.style.width = this.data.cropperFrameWidth + 'px';\r\n blockImg.style.height = this.data.cropperFrameHeight + 'px';\r\n\r\n const imageEl = blockImg.getElementsByTagName(\r\n 'img',\r\n )[0] as HTMLImageElement;\r\n if (imageEl) {\r\n imageEl.style.left = this.data.cropperFrameLeft + 'px';\r\n imageEl.style.top = this.data.cropperFrameTop + 'px';\r\n imageEl.classList.add('isCropped');\r\n }\r\n\r\n blockEl.classList.remove('isCropping');\r\n\r\n const cropSaveBtn = blockContent.getElementsByClassName(\r\n 'btn-crop-action',\r\n )[0] as HTMLElement;\r\n if (cropSaveBtn) {\r\n blockImg.removeChild(cropSaveBtn);\r\n }\r\n }\r\n\r\n //remove cropper interface\r\n if (this.data.cropperInterface) {\r\n this.data.cropperInterface.destroy();\r\n this.data.cropperInterface = undefined;\r\n }\r\n\r\n //add crop button\r\n if (this.api.readOnly.isEnabled) return;\r\n const cropBtn = document.createElement('div');\r\n cropBtn.classList.add('crop-btn', 'btn-crop-action');\r\n cropBtn.innerHTML = this.api.i18n.t('Crop');\r\n\r\n const imageToolImage = blockContent.getElementsByClassName(\r\n 'image-tool__image',\r\n )[0] as HTMLElement;\r\n if (imageToolImage) {\r\n cropBtn.addEventListener('click', () => {\r\n //remove crop button\r\n imageToolImage.removeChild(cropBtn);\r\n this.appendCrop(blockContent);\r\n });\r\n\r\n imageToolImage.appendChild(cropBtn);\r\n }\r\n\r\n blockContent.classList.remove('isCropping');\r\n this.block.dispatchChange();\r\n }\r\n\r\n uncrop(blockContent: HTMLElement): void {\r\n if (this.api.readOnly.isEnabled) return;\r\n\r\n const imageEl = blockContent.getElementsByClassName(\r\n 'image-tool__image',\r\n )[0] as HTMLElement;\r\n\r\n //remove crop and save button\r\n const cropSaveBtn = blockContent.getElementsByClassName(\r\n 'btn-crop-action',\r\n )[0] as HTMLElement;\r\n if (cropSaveBtn && imageEl) {\r\n imageEl.removeChild(cropSaveBtn);\r\n }\r\n\r\n //remove crop button\r\n const cropBtn = blockContent.getElementsByClassName(\r\n 'btn-crop-action',\r\n )[0] as HTMLElement;\r\n if (cropBtn && imageEl) {\r\n imageEl.removeChild(cropBtn);\r\n }\r\n\r\n //remove isCropped class\r\n const blockEl = blockContent.getElementsByClassName(\r\n 'cdx-block',\r\n )[0] as HTMLElement;\r\n if (blockEl) {\r\n const image = blockEl.getElementsByTagName('img')[0] as HTMLImageElement;\r\n if (image) image.classList.remove('isCropped');\r\n\r\n //remove isCropping class\r\n blockEl.classList.remove('isCropping');\r\n\r\n //remove min and max width\r\n blockEl.style.minWidth = '';\r\n blockEl.style.maxWidth = '';\r\n }\r\n\r\n if (imageEl) {\r\n //remove image width and height\r\n imageEl.style.width = '';\r\n imageEl.style.height = '';\r\n\r\n //remove image left and top\r\n const image = imageEl.getElementsByTagName('img')[0] as HTMLImageElement;\r\n if (image) {\r\n image.style.left = '';\r\n image.style.top = '';\r\n\r\n //remove image width and height\r\n image.style.width = '';\r\n image.style.height = '';\r\n }\r\n }\r\n\r\n blockContent.classList.remove('isCropping');\r\n\r\n //remove cropper interface\r\n if (this.data.cropperInterface) {\r\n this.data.cropperInterface.destroy();\r\n this.data.cropperInterface = undefined;\r\n }\r\n\r\n //remove crop data\r\n this.data.cropperFrameHeight = 0;\r\n this.data.cropperFrameWidth = 0;\r\n this.data.cropperFrameLeft = 0;\r\n this.data.cropperFrameTop = 0;\r\n this.data.cropperImageHeight = 0;\r\n this.data.cropperImageWidth = 0;\r\n }\r\n\r\n /**\r\n * Add resize handles to block\r\n * @param {HTMLElement} blockContent - wrapper for block content\r\n * @public\r\n * @return {void}\r\n * */\r\n resize(blockContent: HTMLElement): void {\r\n if (this.api.readOnly.isEnabled) return;\r\n const resizable = document.createElement('div');\r\n resizable.classList.add('resizable');\r\n\r\n const resizers = document.createElement('div');\r\n resizers.classList.add('resizers');\r\n\r\n const resizerTopRight = document.createElement('div');\r\n resizerTopRight.classList.add('resizer', 'top-right');\r\n resizerTopRight.addEventListener('mousedown', e => {\r\n this.resizeClick(\r\n blockContent.getElementsByClassName('cdx-block')[0] as HTMLElement,\r\n resizerTopRight,\r\n e,\r\n );\r\n });\r\n\r\n const resizerBottomRight = document.createElement('div');\r\n resizerBottomRight.classList.add('resizer', 'bottom-right');\r\n resizerBottomRight.addEventListener('mousedown', e => {\r\n this.resizeClick(\r\n blockContent.getElementsByClassName('cdx-block')[0] as HTMLElement,\r\n resizerBottomRight,\r\n e,\r\n );\r\n });\r\n\r\n resizers.appendChild(resizerTopRight);\r\n resizers.appendChild(resizerBottomRight);\r\n resizable.appendChild(resizers);\r\n blockContent.getElementsByClassName('cdx-block')[0].appendChild(resizable);\r\n }\r\n\r\n /**\r\n * click event to resize handles\r\n * preserve aspect ratio\r\n * prevent block from moving when dragging resize handles\r\n * max size = 100%\r\n * min size = 50px\r\n * @param {HTMLElement} blockContent - wrapper for block content\r\n * @param {HTMLElement} handle - resize handle\r\n * @param {MouseEvent} e - mouse event\r\n * @public\r\n * @return {void}\r\n * */\r\n resizeClick(blockContent: HTMLElement, _: HTMLElement, e: MouseEvent): void {\r\n const maxWidth =\r\n document.getElementsByClassName('codex-editor')[0].clientWidth;\r\n\r\n let startX = 0;\r\n let startWidth = 0;\r\n\r\n const mouseMoveHandler = (e: MouseEvent) => {\r\n const dx = e.clientX - startX;\r\n const newWidth = startWidth + dx;\r\n\r\n if (newWidth > 50 && newWidth < maxWidth) {\r\n (\r\n blockContent as HTMLElement & { style: CSSStyleDeclaration }\r\n ).style.width = newWidth + 'px';\r\n }\r\n };\r\n\r\n const mouseUpHandler = () => {\r\n const blockWidth = parseInt(\r\n window.getComputedStyle(blockContent).width,\r\n 10,\r\n );\r\n\r\n if (blockWidth > 0) {\r\n this.data.resizeSize = blockWidth;\r\n }\r\n\r\n document.removeEventListener('mousemove', mouseMoveHandler);\r\n document.removeEventListener('mouseup', mouseUpHandler);\r\n\r\n this.block.dispatchChange();\r\n };\r\n\r\n document.addEventListener('mousemove', mouseMoveHandler);\r\n document.addEventListener('mouseup', mouseUpHandler);\r\n\r\n startX = e.clientX;\r\n startWidth = parseInt(window.getComputedStyle(blockContent).width, 10);\r\n }\r\n\r\n /**\r\n * Remove resize handles from block\r\n * @param {HTMLElement} blockContent - wrapper for block content\r\n * @public\r\n * @return {void}\r\n */\r\n unresize(blockContent: HTMLElement): void {\r\n const unresizable = blockContent.getElementsByClassName(\r\n 'resizable',\r\n )[0] as HTMLElement;\r\n if (unresizable) {\r\n blockContent\r\n .getElementsByClassName('cdx-block')[0]\r\n .removeChild(unresizable);\r\n }\r\n\r\n const block: HTMLElement = blockContent.getElementsByClassName(\r\n 'cdx-block',\r\n )[0] as HTMLElement;\r\n block.style.width = 'auto';\r\n }\r\n\r\n /**\r\n * Remove tunes from block wrapper\r\n * @param {HTMLElement} blockContent - wrapper for block content\r\n * @public\r\n * @return {HTMLElement}\r\n */\r\n unwrap(blockContent: HTMLElement): HTMLElement {\r\n //remove tunes from block\r\n this.buttons.forEach(button => {\r\n button.classList.remove(this.CSS.buttonActive);\r\n });\r\n\r\n //remove isFloatLeft class\r\n blockContent.classList.remove(this.CSS.isFloatLeft);\r\n\r\n //remove isFloatRight class\r\n blockContent.classList.remove(this.CSS.isFloatRight);\r\n\r\n //remove isCenter class\r\n blockContent.classList.remove(this.CSS.isCenter);\r\n\r\n //remove isSizeSmall class\r\n blockContent.classList.remove(this.CSS.isSizeSmall);\r\n\r\n //remove isSizeMiddle class\r\n blockContent.classList.remove(this.CSS.isSizeMiddle);\r\n\r\n //remove isSizeLarge class\r\n blockContent.classList.remove(this.CSS.isSizeLarge);\r\n\r\n //remove isResize class\r\n blockContent.classList.remove(this.CSS.isResize);\r\n\r\n //remove isCrop class\r\n blockContent.classList.remove(this.CSS.isCrop);\r\n\r\n //remove isCropped class\r\n const cdxBlock = blockContent.getElementsByClassName(\r\n 'cdx-block',\r\n )[0] as HTMLElement;\r\n const img = cdxBlock.getElementsByTagName('img')[0] as HTMLImageElement;\r\n img.classList.remove('isCropped');\r\n\r\n //remove isCropping class\r\n cdxBlock.classList.remove('isCropping');\r\n\r\n //remove min and max width\r\n cdxBlock.style.minWidth = '';\r\n cdxBlock.style.maxWidth = '';\r\n\r\n //remove image width and height\r\n const imageToolImage = blockContent.getElementsByClassName(\r\n 'image-tool__image',\r\n )[0] as HTMLElement;\r\n imageToolImage.style.width = '';\r\n imageToolImage.style.height = '';\r\n\r\n //remove image left and top\r\n const image = imageToolImage.getElementsByTagName(\r\n 'img',\r\n )[0] as HTMLImageElement;\r\n image.style.left = '';\r\n image.style.top = '';\r\n\r\n //remove image width and height\r\n image.style.width = '';\r\n image.style.height = '';\r\n\r\n //remove resize handles\r\n this.unresize(blockContent);\r\n\r\n //remove crop handles\r\n this.uncrop(blockContent);\r\n\r\n //remove cropper interface\r\n if (this.data.cropperInterface) {\r\n this.data.cropperInterface.destroy();\r\n this.data.cropperInterface = undefined;\r\n }\r\n\r\n //remove crop data\r\n this.data.cropperFrameHeight = 0;\r\n this.data.cropperFrameWidth = 0;\r\n this.data.cropperFrameLeft = 0;\r\n this.data.cropperFrameTop = 0;\r\n this.data.cropperImageHeight = 0;\r\n this.data.cropperImageWidth = 0;\r\n\r\n return blockContent;\r\n }\r\n\r\n /**\r\n * Add tune to block data\r\n * @private\r\n * @return {ImageToolTuneData}\r\n * */\r\n save(): ImageToolTuneData {\r\n return this.data;\r\n }\r\n\r\n /**\r\n * Append tunes to block wrapper\r\n * @param {HTMLElement} blockContent - wrapper for block content\r\n * @public\r\n * @return {HTMLElement}\r\n * */\r\n wrap(blockContent: HTMLElement): HTMLElement {\r\n //createview if not exists\r\n if (!this.wrapper) {\r\n this.wrapper = this.createView();\r\n }\r\n\r\n this.apply(blockContent);\r\n return blockContent;\r\n }\r\n\r\n private tuneNameToI18nKey(tuneName: string): string {\r\n const translation: Record<string, string> = {\r\n crop: 'Crop',\r\n resize: 'Resize',\r\n };\r\n return translation[tuneName];\r\n }\r\n\r\n /**\r\n * Creates a view for tunes\r\n * @return {HTMLElement}\r\n * @private\r\n * */\r\n createView(): HTMLElement {\r\n this.buttons = this.settings.map(tune => {\r\n const el = document.createElement('div');\r\n const buttonIco = document.createElement('span');\r\n const buttonTxt = document.createElement('span');\r\n el.classList.add(this.CSS.button);\r\n buttonTxt.style.fontSize = '8px';\r\n buttonIco.innerHTML = tune.icon;\r\n buttonTxt.innerHTML = tune.label;\r\n el.appendChild(buttonIco);\r\n el.appendChild(buttonTxt);\r\n el.dataset.tune = tune.name;\r\n el.title = tune.label;\r\n\r\n el.addEventListener('click', e => this.tuneClicked(e, el));\r\n this.api.tooltip.onHover(\r\n el,\r\n this.api.i18n.t(this.tuneNameToI18nKey(tune.name)),\r\n );\r\n return el;\r\n });\r\n const wrapper = document.createElement('div');\r\n this.buttons.forEach(button => {\r\n wrapper.appendChild(button);\r\n });\r\n wrapper.classList.add(this.CSS.wrapper);\r\n return wrapper;\r\n }\r\n\r\n /**\r\n * Checks if tune is active\r\n * @param {string} tune - tune name\r\n * @return {boolean}\r\n * @private\r\n * */\r\n isTuneActive(tune: string): boolean {\r\n return !!this.data[tune as keyof ImageToolTuneData];\r\n }\r\n\r\n /**\r\n * Makes buttons with tunes\r\n * @return {HTMLElement}\r\n * @public\r\n * */\r\n render(): HTMLElement {\r\n //when editor is ready\r\n this.buttons.forEach(button => {\r\n const tuneName = button.dataset.tune || '';\r\n button.classList.toggle(\r\n this.CSS.buttonActive,\r\n this.isTuneActive(tuneName),\r\n );\r\n });\r\n\r\n return this.view;\r\n }\r\n\r\n /**\r\n * Destroys the plugin\r\n * @public\r\n * @return {void}\r\n * */\r\n destroy(): void {\r\n this.wrapper = undefined;\r\n this.buttons = [];\r\n }\r\n\r\n /**\r\n * Toggle tune\r\n * @param {string} tuneName - tune name\r\n * @private\r\n * @return {void}\r\n * */\r\n _toggleTune(tuneName: string): void {\r\n this.setTune(tuneName);\r\n }\r\n}\r\n","<template>\r\n <div class=\"ebl-editor\" id=\"holder\">\r\n <!-- <div class=\"ce-block__content ebl-editor-title-wrap\">\r\n <input type=\"text\" v-model=\"title\" placeholder=\"请输入标题\" class=\"ebl-editor-title-input\"></input>\r\n </div> -->\r\n <!-- <div class=\"ce-block__content ebl-editor-time-wrap\">\r\n <span class=\"ebl-editor-time\">最后修改时间:{{ lastUpdateTime }}</span>\r\n </div> -->\r\n <button @click=\"validate\">保存</button> \r\n\r\n </div>\r\n</template>\r\n<script lang=\"ts\" setup>\r\n\r\nimport EditorJS from '@ebl-vue/editorjs';\r\n//import EditorJS from '../../../../editorjs/src/codex';\r\n//window.VERSION=\"2.31.0\"; //如果是用源码模式时,需要设置全局变量\r\n\r\nimport { onMounted, onUnmounted, ref, inject } from 'vue';\r\nimport { toRaw } from 'vue';\r\nimport { IEblEditorSettings } from '@/types';\r\n\r\n/**\r\n * 插件\r\n */\r\n\r\nimport DragDrop from '../../plugins/drag-drop';\r\nimport { H1, H2, H3, H4, H5, H6 } from '../../plugins/header';\r\nimport BlockAlignment from '../../plugins/block-alignment';\r\nimport Paragraph from '../../plugins/paragraph';\r\nimport Code from '../../plugins/code';\r\nimport type { OutputData } from '@ebl-vue/editorjs';\r\nimport Quote from \"../../plugins/quote/\";\r\nimport Delimiter from '../../plugins/delimiter';\r\nimport List from '../../plugins/list';\r\nimport Undo from '../../plugins/undo';\r\nimport Alert from '../../plugins/alert';\r\nimport IndentTune from '../../plugins/indent';\r\nimport Marker from \"../../plugins/marker\";\r\nimport { ColorPickerWithoutSanitize } from \"../../plugins/color-picker\";\r\nimport Underline from \"../../plugins/underline\";\r\nimport InlineCode from \"../../plugins/inline-code\";\r\nimport Table from '../../plugins/table';\r\nimport ImageTool from \"../../plugins/imageTool\";\r\nimport {ImageToolTune } from \"../../plugins/imageResizeCrop\";\r\n\r\nconst EblEditorSettings: IEblEditorSettings | undefined = inject(\"EblEditorSettings\");\r\n\r\ndefineOptions({\r\n name: 'EblEditor',\r\n inheritAttrs: false\r\n})\r\n\r\n\r\nlet emits = defineEmits([\"onReady\", \"onChange\"]);\r\n\r\n\r\ninterface Props {\r\n readOnly: boolean,\r\n placeholder: string,\r\n data: OutputData,\r\n locale: any,\r\n userStore:any\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n readOnly: false,\r\n placeholder: \"Enter something\",\r\n data: ()=>({\r\n blocks: []\r\n }),\r\n locale:{}\r\n});\r\n\r\n\r\n\r\nlet editor: EditorJS | null = null;\r\nconst tunes = ['indent', 'blockAlignment'];\r\nonMounted(() => {\r\n const editorData=toRaw(props.data);\r\n editor = new EditorJS({\r\n holder: 'holder',\r\n autofocus: true,\r\n defaultBlock: 'paragraph',\r\n placeholder: props.placeholder,\r\n tunes: tunes,\r\n tools: {\r\n inlineCode: InlineCode,\r\n underline: Underline,\r\n Color: {\r\n class: ColorPickerWithoutSanitize\r\n },\r\n marker: {\r\n class: Marker\r\n },\r\n indent: {\r\n class: IndentTune,\r\n },\r\n alert: {\r\n class: Alert,\r\n inlineToolbar: true\r\n },\r\n List: {\r\n class: List,\r\n inlineToolbar: true,\r\n config: {\r\n defaultStyle: 'unordered',\r\n }\r\n },\r\n h1: {\r\n class: H1,\r\n inlineToolbar: true\r\n },\r\n h2: {\r\n class: H2,\r\n inlineToolbar: true,\r\n\r\n },\r\n h3: {\r\n class: H3,\r\n inlineToolbar: true\r\n },\r\n h4: {\r\n class: H4,\r\n inlineToolbar: true\r\n },\r\n h5: {\r\n class: H5,\r\n inlineToolbar: true\r\n },\r\n h6: {\r\n class: H6,\r\n inlineToolbar: true\r\n },\r\n paragraph: {\r\n class: Paragraph,\r\n inlineToolbar: true\r\n },\r\n blockAlignment: {\r\n class: BlockAlignment,\r\n inlineToolbar: true\r\n },\r\n code: {\r\n class: Code,\r\n config: {\r\n lang: \"javascript\",\r\n theme: \"catppuccin-latte\"\r\n }\r\n },\r\n quote: {\r\n class: Quote,\r\n inlineToolbar: true\r\n },\r\n delimiter: Delimiter,\r\n table: {\r\n class: Table,\r\n inlineToolbar: true,\r\n config: {\r\n rows: 2,\r\n cols: 3,\r\n }\r\n },\r\n image: {\r\n class: ImageTool,\r\n inlineToolbar: true,\r\n tunes: tunes.concat(['imageResize']),\r\n config: {\r\n types:\".png,.jpeg,.jpg,.gif,.webp\",\r\n userStore: props.userStore,\r\n endpoints: {\r\n byFile: EblEditorSettings?.fileUploadEndpoint,\r\n byUrl: EblEditorSettings?.urlUploadEndpoint\r\n },\r\n features: {\r\n caption: false,\r\n stretch: false,\r\n border: false,\r\n background: false,\r\n }\r\n \r\n \r\n }\r\n },\r\n imageResize: {\r\n class: ImageToolTune ,\r\n config: {\r\n resize: true,\r\n crop: false\r\n }\r\n },\r\n\r\n\r\n\r\n },\r\n \r\n data: editorData,\r\n readOnly: props.readOnly,\r\n i18n: props.locale,\r\n onChange: (api, event) => {\r\n emits(\"onChange\", api, event);\r\n },\r\n onReady: () => {\r\n new DragDrop(\"holder\", props.readOnly, editor!, '1px solid #999');\r\n const undoConfig = {\r\n debounceTimer: 200,\r\n maxLength:100\r\n }\r\n const undo = new Undo({\r\n editor: editor!,\r\n config: undoConfig,\r\n onUpdate: () => {\r\n }\r\n });\r\n undo.initialize(editorData);\r\n emits(\"onReady\");\r\n },\r\n\r\n })\r\n});\r\nonUnmounted(() => {\r\n if (editor !== null) {\r\n editor.destroy();\r\n editor = null;\r\n }\r\n});\r\n\r\n/**\r\n * 验证是否为空 */\r\nfunction validate() {\r\n return new Promise((resolve, reject) => {\r\n if (editor !== null) {\r\n editor.save().then((outputData: OutputData) => {\r\n if (outputData.blocks.length > 0) {\r\n return resolve(true);\r\n\r\n }\r\n return resolve(false);\r\n });\r\n } else {\r\n return resolve(false);\r\n }\r\n });\r\n}\r\nfunction getData() {\r\n return new Promise((resolve, reject) => {\r\n if (editor !== null) {\r\n editor.save().then((outputData: OutputData) => {\r\n return resolve(outputData);\r\n });\r\n } else {\r\n return resolve(null);\r\n }\r\n });\r\n}\r\n\r\ndefineExpose({\r\n validate,\r\n getData,\r\n});\r\n</script>\r\n<style scoped></style>","\r\nimport type { Plugin } from \"vue\";\r\nimport { withInstall } from \"../utils/install\" \r\nimport type { SFCWithInstall } from 'types'\r\n\r\n\r\nimport Editor from \"./Editor/Editor.vue\"\r\n\r\n\r\n\r\n\r\nconst items = [ \r\n Editor \r\n];\r\n\r\nlet PluginList: Plugin[] = [];\r\nfor (let key in items) { \r\n const ele = items[key];\r\n const EblEle: SFCWithInstall<typeof ele> = withInstall(ele);\r\n \r\n PluginList.push(EblEle);\r\n}\r\n\r\nexport default PluginList;\r\nexport {\r\n Editor as EblEditor\r\n };","import type { I18nConfig } from \"@ebl-vue/editorjs/types/configs/i18n-config\";\r\n\r\nconst zhCn: I18nConfig = {\r\n messages: {\r\n \"ui\": {\r\n \"blockTunes\": {\r\n \"toggler\": {\r\n \"Click to tune\": \"可拖拽和点击\"\r\n },\r\n },\r\n\r\n \"toolbar\": {\r\n \"toolbox\": {\r\n \"Add\": \"添加\",\r\n \"Filter\": \"过滤\",\r\n \"Nothing found\": \"无内容\"\r\n },\r\n \"popover\": {\r\n \"Filter\": \"过滤\",\r\n \"Nothing found\": \"无内容\"\r\n }\r\n },\r\n \"popover\": {\r\n \"Filter\": \"筛选\",\r\n \"Nothing found\": \"未找到任何内容\",\r\n /**\r\n * Translation of \"Convert To\" at the Block Tunes Popover\r\n */\r\n \"Convert to\": \"转化为\",\r\n \r\n }\r\n },\r\n \"toolNames\": {\r\n \"Text\": \"段落\",\r\n \"H1\": \"一级标题\",\r\n \"H2\": \"二级标题\",\r\n \"H3\": \"三级标题\",\r\n \"H4\": \"四级标题\",\r\n \"H5\": \"五级标题\",\r\n \"H6\": \"六级标题\",\r\n \"Ordered List\": \"有序列表\",\r\n \"Unordered List\": \"无序列表\",\r\n \"Checklist\": \"任务列表\",\r\n \"Quote\": \"引用\",\r\n \"Code\": \"代码块\",\r\n \"Delimiter\": \"分割线\",\r\n \"Link\": \"链接\",\r\n \"Bold\": \"加粗\",\r\n \"Italic\": \"倾斜\",\r\n \"Alert\": \"高亮块\",\r\n \"indent\": \"缩进\",\r\n \"Marker\": \"突出显示\",\r\n \"Color\": \"文本颜色\",\r\n \"Underline\": \"下划线\",\r\n \"InlineCode\": \"行内代码\",\r\n \"Table\": \"表格\",\r\n \"Image\": \"图片\",\r\n\r\n\r\n\r\n },\r\n \"tools\": {\r\n image: {\r\n \"Couldn’t upload image. Please try another.\": \"上传图片失败,请稍后重试。\"\r\n },\r\n table: {\r\n \"Add row above\": \"在下面插入行\",\r\n \"Add row below\": \"在下面插入行\",\r\n \"Delete row\": \"删除行\",\r\n \"Add column to left\": \"在左边插入列\",\r\n \"Add column to right\": \"在右边插入列\",\r\n \"Delete column\": \"删除列\",\r\n \"With headings\": \"使用标题行\",\r\n \"Without headings\": \"不使用标题行\"\r\n\r\n\r\n },\r\n \"marker\": {\r\n \"Marker\": \"突出显示\"\r\n },\r\n link: {\r\n \"Add a link\":\"添加链接\",\r\n \"Save\": \"保存\",\r\n \"Pasted link is not valid.\":\"链接地址无效\"\r\n },\r\n \"List\": {\r\n \"Unordered\": \"无序\",\r\n \"Ordered\": \"有序\",\r\n \"Checklist\": \"任务列表\",\r\n \"Counter type\": \"计数器类型\",\r\n \"Numeric\": \"阿拉伯数字\",\r\n \"Lower Roman\": \"小写罗马数字\",\r\n \"Upper Roman\": \"大写罗马数字\",\r\n \"Lower Alpha\": \"小写字母\",\r\n \"Upper Alpha\": \"大写字母\",\r\n \"Start with\": \"从\"\r\n },\r\n \"paragraph\": {\r\n \"Enter something\": \"请输入内容\",\r\n },\r\n\r\n \"stub\": {\r\n 'The block can not be displayed correctly.': '该模块不能放置在这里'\r\n },\r\n\r\n \"code\": {\r\n \"Enter your code\": \"输入代码\",\r\n \"Copied\": \"已复制\"\r\n },\r\n \"convertTo\": {\r\n \"Convert to\": \"转化为\"\r\n },\r\n \"alert\": {\r\n \"alert-primary\": \"主要样式\",\r\n \"alert-secondary\": \"次要样式\",\r\n \"alert-info\": \"信息\",\r\n \"alert-success\": \"成功\",\r\n \"alert-warning\": \"警告\",\r\n \"alert-danger\": \"危险\",\r\n \"alert-light\": \"浅色\",\r\n \"alert-dark\": \"深色\",\r\n \"align-left\": \"左对齐\",\r\n \"align-center\": \"居中\",\r\n \"align-right\": \"右对齐\" \r\n }\r\n },\r\n \"blockTunes\": {\r\n \r\n \"delete\": {\r\n \"Delete\": \"删除\",\r\n 'Click to delete': \"点击删除\"\r\n },\r\n \"moveUp\": {\r\n \"Move up\": \"向上移\"\r\n },\r\n \"moveDown\": {\r\n \"Move down\": \"向下移\"\r\n },\r\n \"filter\": {\r\n \"Filter\": \"过滤\"\r\n },\r\n \"blockAlignment\": {\r\n \"left align\": \"左对齐\",\r\n \"center align\": \"居中对齐\",\r\n \"right align\": \"右对齐\",\r\n \"justify align\": \"两端对齐\",\r\n },\r\n \"indent\": {\r\n \"Indent right\": \"向右缩进\",\r\n \"Indent left\": \"向左缩进\"\r\n },\r\n },\r\n }\r\n}\r\n\r\nexport default zhCn;","\r\n\r\nimport './style.css'\r\nimport { createInstaller } from './installer'\r\nimport Components from './components';\r\nimport zhCn from './i18n/zh-cn';\r\nimport type { OutputData } from '@ebl-vue/editorjs';\r\nimport Editor from './components/Editor/Editor.vue';\r\nconst installer = createInstaller(Components)\r\nexport const install = installer.install\r\nexport const version = installer.version\r\nexport default installer;\r\n\r\nexport {\r\n zhCn,\r\n Editor as EblEditor\r\n};\r\nexport type { OutputData };","import type { App, Plugin } from 'vue'\r\nimport { version } from '../package.json'\r\n\r\nimport { INSTALLED_KEY } from \"./constants\";\r\nimport { IEblEditorSettings } from '@/types';\r\n\r\nexport const createInstaller = (components: Plugin[] = []) => {\r\n const install = (app: App,config?: IEblEditorSettings) => {\r\n if (app[INSTALLED_KEY]) return\r\n\r\n app[INSTALLED_KEY] = true\r\n components.forEach((c) => app.use(c)) \r\n if(config) {\r\n app.provide(\"EblEditorSettings\",config);\r\n }\r\n \r\n }\r\n\r\n return {\r\n version,\r\n install,\r\n }\r\n}"],"names":["INSTALLED_KEY","Symbol","withInstall","main","extra","install","app","comp","Object","values","component","name","DragDrop","holderId","readonly","editor","borderStyle","blocks","toolbar","this","api","holder","document","getElementById","readOnly","startBlock","endBlock","setDragListener","setDropListener","element","range","createRange","selection","window","getSelection","setStart","childNodes","collapse","removeAllRanges","addRange","focus","settingsButton","querySelector","initializeDragListener","MutationObserver","mutations","obs","disconnect","observe","childList","subtree","setAttribute","addEventListener","getCurrentBlockIndex","close","isTheOnlyBlock","allBlocks","querySelectorAll","blockFocused","setElementCursor","setBorderBlocks","forEach","block","blockContent","style","removeProperty","index","keys","find","key","Number","borderBottom","borderTop","event","target","contains","dropTarget","getDropTarget","getTargetPosition","moveBlocks","isReadOnlySupported","classList","closest","Array","from","parentNode","children","indexOf","getBlocksCount","move","IconH1","IconH2","IconH3","IconH4","IconH5","IconH6","IconAlignCenter","IconAlignLeft","IconAlignRight","IconCross","IconMarker","IconPicture","IconText","IconIndentLeft","IconIndentRight","H1","data","config","_settings","placeholder","_data","normalizeData","_element","getTag","_CSS","styles","wrapper","text","newData","level","defaultLevel","number","isHeaderData","isNaN","parseInt","toString","render","insertAdjacentHTML","blockData","trim","toolsContent","innerHTML","export","import","newHeader","replaceChild","tag","createHeadingElement","setElementContent","addStylesToElement","setEditability","addPlaceholder","createElement","add","contentEditable","dataset","i18n","t","svg","detail","content","pasteConfig","tags","icon","title","H2","constructor","conversionConfig","sanitize","H3","toolbox","H4","H5","H6","BlockAlignment","isTune","settings","hasOwnProperty","default","DEFAULT_ALIGNMENT","alignment","getAlignment","alignmentSettings","left","center","right","toggle","append","map","align","button","type","settingsButtonActive","buttonTooltip","tooltip","onHover","placement","appendChild","elements","el","i","Paragraph","onKeyUp","bind","_placeholder","DEFAULT_PLACEHOLDER","_preserveBlank","preserveBlank","e","code","textContent","drawView","div","placeholderActive","fragment","htmlString","tempDiv","createDocumentFragment","normalize","savedData","requestAnimationFrame","br","CodeTool","_selectorLanguage","_selectorTheme","lang","DEFAULT_LANGUAGE","theme","DEFAULT_THEME","CSS","baseClass","input","textarea","span","selectorLanguage","selectorTheme","nodes","enableLineBreaks","codeWrapper","value","stopPropagation","preventDefault","isShiftPressed","shiftKey","caretPosition","selectionStart","indentation","newCaretPosition","currentLineStart","string","position","char","substr","substring","setSelectionRange","wrapperHolder","wrapperSelectorHolder","wrapperLang","wrapperCopy","wrapperCopyTip","innerText","languages","option","id","spellcheck","autocomplete","autocapitalize","disabled","runShiki","then","html","preStyle","tabHandler","copyCode","codeToHtml","transformers","preprocess","node","addClassToHast","properties","navigator","clipboard","writeText","parentEle","parentElement","lastChild","setTimeout","remove","catch","err","alert","Quote","contentless","quoteData","container","make","_quoteElement","handleKeydown","currentNode","anchorNode","nodeType","Node","ELEMENT_NODE","currentItem","getOutOfQuote","length","currentBlockIndex","delete","insert","caret","setToBlock","quoteElement","assign","Delimiter","lineWrapper","lineDiv","CssPrefix","DefaultListCssClasses","item","itemContent","itemChildren","OrderedListRenderer","orderedList","isRoot","wrapperElement","_meta","itemWrapper","contentNode","isEmpty","UnorderedListRenderer","unorderedList","isHtmlElement","CheckListRenderer","checklist","itemChecked","noHover","checkbox","checkboxContainer","checkboxCheckDisabled","toggleCheckbox","meta","checked","composeDefaultMeta","removeSpecialHoverBehavior","once","getSiblings","direction","siblings","nextElementSibling","getNextElementSibling","previousElementSibling","push","getChildItems","firstLevelChildren","itemChildWrapper","getItemChildWrapper","removeChildWrapperIfEmpty","getItemContentElement","focusItem","atStart","ListTabulator","levelCounter","listWrapper","renderer","renderWrapper","items","appendItems","enterPressed","backspace","shiftTab","addTab","start","changeStartWith","counterType","changeCounters","getItems","parent","subItemsWrapper","getItemContent","getItemMeta","composedListItems","dataToSave","deepestBlockItem","deepestBlockItemContentElement","firstLevelItems","lastFirstLevelItemChildWrapper","firstItem","shift","list","pasteHandler","oldView","tagName","tagToSearch","getPastedItems","child","subItems","setProperty","isComposing","isFirstLevelItem","isFirstItem","splitList","convertItemToDefaultBlock","unshiftItem","splitItem","isCaretAtStartOfInput","isCollapsed","mergeItemWithPrevious","convertFirstItemToDefaultBlock","parentItem","currentItemChildWrapper","sibling","after","currentItemChildrenList","currentBlock","firstChildItem","newListItems","newListWrapper","newListItem","newListContent","save","offset","getCaretNodeAndOffset","currentItemContent","endingHTML","getContenteditableSlice","itemEl","renderItem","previousItem","currentItemParentNode","targetItem","childrenOfPreviousItem","targetItemContentElement","targetForChildItems","targetChildWrapper","childItem","prepend","maxLevel","currentItemLevel","prevItem","previousSibling","prevItemChildrenList","prevItemChildrenListWrapper","newBloxkIndex","removeList","newBlock","currentItemChildren","currentItemSiblings","itemMeta","sublistWrapper","OlCounterTypesMap","Map","EditorjsList","joinRecursive","defaultStyle","listStyle","defaultListStyle","changeTabulatorByStyle","newListElement","listElement","replaceWith","defaultCounterTypes","counterTypes","initialData","normalizedDataItems","structuredClone","join","merge","onPaste","Observer","registerChange","debounceTimer","observer","mutationDebouncer","debounce","setMutationObserver","mutationList","mutationHandler","attributes","characterData","characterDataOldValue","contentMutated","mutation","onDestroy","callback","wait","timeout","args","context","clearTimeout","apply","destroyEvent","CustomEvent","dispatchEvent","Undo","onUpdate","maxLength","defaultOptions","shortcuts","undo","redo","configuration","defaultBlock","defaultShortcuts","configShortcuts","isArray","defaultDebounceTimer","shouldSaveHistory","setEventListeners","initialItem","clear","stack","limit","firstElement","state","setReadOnly","editorDidUpdate","JSON","stringify","truncate","Math","min","slice","blockCount","indexInState","caretIndex","getCaretIndex","getElementsByClassName","VanillaCaret","firstChild","getPos","compState","some","compIndex","canUndo","nextIndex","nextState","blockWasDeleted","insertDeletedBlock","contentWasCopied","blockWasSkipped","setCaretIndex","blockWasDropped","contentChangedInNoFocusBlock","getBlockByIndex","update","caretBlock","setPos","insertBlock","insertSkippedBlocks","prevState","updateModifiedBlock","getById","canRedo","prevIndex","count","specialKeys","CMD","test","platform","ALT","SHIFT","parsedKeys","letterKey","includes","toUpperCase","toLowerCase","keysUndo","undoShortcut","replace","split","keysRedo","redoShortcut","keysUndoParsed","parseKeys","keysRedoParsed","verifyListThreeKeysPressed","keysList","reduce","result","threeKeysPressed","pressedKeys","compKeys","handleUndo","handleRedo","removeEventListener","Alert","DEFAULT_ALIGN_TYPE","ALIGN_TYPES","wrapperForType","wrapperForAlignType","alignType","message","alertTypes","ALERT_TYPES","defaultType","DEFAULT_TYPE","defaultAlign","messagePlaceholder","DEFAULT_MESSAGE_PLACEHOLDER","containerClasses","_make","messageEl","classname","renderSettings","alertWrapper","alignWrapper","_getSettingIconStyle","buttons","getAttribute","_changeAlertType","elType","AlignLeftIcon","AlignRightIcon","AlignCenterIcon","_changeAlignType","elAlign","charAt","newType","alertClass","newAlign","alignClass","alertElement","classNames","attrName","warnings","orientation","IndentTune","other","DEFAULT_INDENT_KEY","lastResizeTimeout","cachedMaxWidthForContent","indentSize","maxIndent","minIndent","multiblock","autoIndent","tuneName","customBlockIndentLimits","handleShortcut","directionChangeHandler","version","changeConfigBasedOnVersionIfNeeded","alignmentChangeListener","defaultIndentLevel","indentLevel","onResize","call","events","on","targetId","currentBlockId","shouldApplyAutoIndent","queueMicrotask","autoIndentBlock","disableItemOnRender","getTuneButton","disabledItem","leftElementName","TuneNames","indentLeft","rightElementName","indentRight","rightText","hint","onActivate","handleIndentRight","leftText","handleIndentLeft","popoverItem","customPopoverItem","popoverItemIcon","popoverItemTitle","sanitizer","clean","createElementFromTemplate","rightBtn","leftBtn","pluginsContent","DATA_WRAPPER_NAME","applyBlockHighlight","Boolean","highlightIndent","tuneNames","highlightEl","className","contentEl","EditorCSS","applyStylesToWrapper","onKeyDown","capture","onFocus","onBlur","redactor","customInterval","max","isDirectionInverted","previousBlockIndex","previousBlock","previousBlockName","isDefaultKeyPressed","isCustomBehaviourDefined","handledCommand","isIndent","handlingResult","handlePropagationForKeyEvent","inlineToolbar","selectedBlocks","getGlobalSelectedBlocks","indentBlock","unIndentBlock","dispatchChange","async","b","tunes","tune","blockWrapper","getWrapperBlockById","HTMLElement","toggleDisableStateForButtons","getBlockIndex","previousBlockIndentLevelAttribute","DATA_INDENT_LEVEL","previousBlockIndentLevel","currentBlockIndentLevel","indentType","indentName","getTuneByName","givenWrapper","indentValue","contentElement","blockElement","getBlockForWrapper","blockWidth","getBoundingClientRect","width","maxApplyableIndent","maxWidthForContent","indentToApply","indentValuePixels","indentValuePixelsForHighlight","paddingLeft","paddingRight","highlightElement","DATA_FOCUSED","removeAttribute","w","fill","_","idx","filter","selected","blockId","selector","current","HTMLHtmlElement","indentRightBtnTitle","getTuneTitleByName","indentLeftBtnTitle","template","DOMParser","parseFromString","body","elementInsideEditor","maxWidth","getComputedStyle","_ut","Marker","toolboxIcon","iconClasses","base","inlineToolButton","active","inlineToolButtonActive","termWrapper","findParentTag","unwrap","wrap","marker","extractContents","insertNode","expandToTag","sel","getRangeAt","unwrappedContent","removeChild","checkState","termTag","mark","class","ColorPicker","defaultColor","lastRange","colors","columns","color","selectedText","renderActions","gridTemplateColumns","colorValue","backgroundColor","onclick","wrapAndColor","ColorPickerWithoutSanitize","Underline","options","u","isInline","_Ct","InlineCode","commonAncestorContainer","prototype","getCoords","elem","rect","y1","floor","top","pageYOffset","x1","pageXOffset","x2","y2","bottom","getRelativeCoordsOfTwoElems","firstElem","secondElem","firstCoords","secondCoords","fromTopBorder","fromLeftBorder","fromRightBorder","fromBottomBorder","insertBefore","newNode","referenceNode","selectNodeContents","Popover","itemEls","popover","popoverOpened","itemHidden","itemConfirmState","itemIcon","itemLabel","$.make","label","popoverClicked","clickedItem","clickedItemIndex","confirmationRequired","hasConfirmationState","onClick","setConfirmationState","open","hideIf","clearConfirmationState","Toolbox","onOpen","onClose","cssModifier","createToolbox","toolboxShowed","toggler","mutationFree","createPopover","createToggler","togglerClicked","opened","computePositionMethod","entries","prop","hide","Table","minCellWidhth","defaultCellWidth","handleDocumentMousedown","isDragging","table","handleDocumentMousemove","handleDocumentMouseup","draggingColumn","hoveredColumn","startWidth","colWidthArr","mouseStartX","clientX","deltaX","newWidth","updateColWidth","updateToolboxesPosition","hoveredCell","focusedCell","row","col","toolboxColumn","createColumnToolbox","toolboxRow","createRowToolbox","createTableWrapper","hoveredRow","selectedRow","selectedColumn","withHeadings","resize","colWidth","column","documentClicked","clickedInsideTable","outsideTableClicked","hideToolboxes","clickedOnAddRowButton","clickedOnAddColumnButton","addRow","addColumn","bindEvents","delay","fn","lastCall","now","Date","getTime","onMouseMoveInTable","passive","onkeypress","onKeyPressListener","onKeyDownListener","focusInTableListener","cells","cell","numberOfColumns","maxcols","deleteColumn","selectColumn","hideRowToolbox","unselectColumn","numberOfRows","maxrows","deleteRow","selectRow","hideColumnToolbox","unselectRow","moveCursorToNextRow","focusCell","getCell","columnIndex","setFocus","numOfColumns","rowIndex","cellElem","createCell","$.insertBefore","getRow","firstCell","$.focus","addColButton","addHeadingAttrToFirstRow","splice","insertedRow","rowElem","removeHeadingAttrFromFirstRow","fillRow","insertedRowFirstCell","getRowFirstCell","addRowButton","computeInitialSize","isValidArray","isNotEmptyArray","contentRows","contentCols","parsedRows","rows","parsedCols","cols","configRows","configCols","j","setCellContent","newCell","childElementCount","deltaXCell","getHoveredCell","cellIsResizable","clientWidth","getRowByCell","focusedCellElem","isColumnMenuShowing","show","isRowMenuShowing","hoveredRowElement","$.getRelativeCoordsOfTwoElems","height","ceil","cellIndex","x","y","clientY","beforeTheLeftBorder1","afterTheRightBorder1","binSearch","mid","beforeTheLeftBorder2","afterTheRightBorder2","deltaYCell","getMousePositionRelateToCell","deltaY","numberOfCells","beforeTheLeftBorder","afterTheRightBorder","leftBorder","rightBorder","totalIterations","relativeCoords","every","destroy","TableBlock","getConfig","stretched","getWrapper","setHeadingsSetting","isActive","closeOnActivate","tableContent","getData","configName","defaultValue","firstRowHeading","UiState","Ui","onSelectFile","imageContainer","fileButton","createFileButton","imageEl","imagePreloader","caption","captionPlaceholder","status","toggleStatus","src","backgroundImage","url","eventName","autoplay","loop","muted","playsinline","statusType","loading","loader","buttonContent","Uploader","onUpload","onError","uploadSelectedFile","onPreview","noSelectedFile","cdn","objectKey","files","fileCancle","Promise","resolve","reject","inputElement","multiple","accept","display","click","types","file","reader","FileReader","readAsDataURL","onload","fileTypes","suffixIndex","lastIndexOf","suffix","headers","userStore","token","tokenName","tokenPrefix","axiosInstance","axios","create","uploadBodyRes","post","endpoints","byFile","fileName","contentType","statusText","uploadRes","success","put","presignedUrl","response","error","upload","byUrl","res","ImageTool","isCaptionEnabled","additionalRequestData","additionalRequestHeaders","field","uploader","actions","features","uploadingFailed","ui","showPreloader","withBorder","withBackground","applyTune","concat","featureTuneMap","border","background","stretch","availableTunes","featureKey","currentState","action","newState","tuneToggled","appendCallback","img","mimeTypes","image","fetch","blob","uploadFile","uploadUrl","fillCaption","setTune","fillImage","errorText","errorMessage","notifier","hidePreloader","deleteCurrentBlock","uploadByFile","uploadByUrl","ImageToolTune","floatLeft","floatRight","sizeSmall","sizeMiddle","sizeLarge","resizeSize","crop","cropperFrameHeight","cropperFrameWidth","cropperFrameLeft","cropperFrameTop","cropperImageHeight","cropperImageWidth","cropperInterface","settingsButtonModifier","settingsButtonModifierActive","buttonActive","buttonModifier","buttonModifierActive","isFloatLeft","isFloatRight","isCenter","isSizeSmall","isSizeMiddle","isSizeLarge","isResize","isCrop","view","createView","tuneGroup","group","unresize","applyCrop","uncrop","isEnabled","cropBtn","appendCrop","cdxBlock","getElementsByTagName","Cropper","cropSaveBtn","getCropBoxData","getCanvasData","getImageData","blockEl","minWidth","blockImg","imageToolImage","resizable","resizers","resizerTopRight","resizeClick","resizerBottomRight","startX","mouseMoveHandler","dx","mouseUpHandler","unresizable","buttonIco","buttonTxt","fontSize","tuneClicked","tuneNameToI18nKey","isTuneActive","EblEditorSettings","inject","emits","__emit","props","__props","validate","outputData","onMounted","editorData","toRaw","EditorJS","autofocus","tools","inlineCode","underline","Color","indent","List","h1","h2","h3","h4","h5","h6","paragraph","blockAlignment","Code","quote","delimiter","fileUploadEndpoint","urlUploadEndpoint","imageResize","locale","onChange","onReady","initialize","onUnmounted","__expose","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","Editor","PluginList","EblEle","zhCn","messages","blockTunes","Add","Filter","toolNames","Text","Checklist","Link","Bold","Italic","Image","link","Save","Unordered","Ordered","Numeric","stub","Copied","convertTo","Delete","moveUp","moveDown","installer","components","c","use","provide","createInstaller","Components"],"mappings":"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"}
|