<template>
<div :style="{'--editor-height': editorHeight}">
	<ckeditor :editor="editor" v-model="editorData" :config="editorConfig" :disabled="disabled" @blur="onBlur" @focus="onFocus"></ckeditor>
</div>
</template>

<script>
import { ClassicEditor, Alignment, AutoImage, Autoformat, BlockQuote, Bold, CodeBlock, DataFilter, DataSchema, Essentials, FindAndReplace,
	FontBackgroundColor, FontColor, FontFamily, FontSize, GeneralHtmlSupport, Heading, Highlight, HorizontalLine, Image, ImageCaption, ImageInsert, ImageResize,
	ImageStyle, ImageToolbar, ImageUpload, Indent, IndentBlock, Italic, Link, LinkImage, List, MediaEmbed, MediaEmbedToolbar, Mention, Paragraph, PasteFromOffice,
	RemoveFormat, SelectAll, ShowBlocks, SourceEditing, SpecialCharacters, SpecialCharactersArrows, SpecialCharactersCurrency, SpecialCharactersEssentials, SpecialCharactersLatin,
	SpecialCharactersMathematical, SpecialCharactersText, Style, Subscript, Superscript, Table, TableCaption, TableCellProperties, TableColumnResize,
	TableProperties, TableToolbar, TextTransformation, TodoList, Underline, Undo, WordCount
} from 'ckeditor5';
import { Ckeditor } from '@ckeditor/ckeditor5-vue';
import { UploadAdapterPlugin } from './UploadAdapter.js'

import coreTranslations from 'ckeditor5/translations/zh-cn.js'
import 'ckeditor5/ckeditor5.css';

export default {
	name: 'scCkeditor',
	props: {
		modelValue: {
			type: String,
			default: ''
		},
		placeholder: {
			type: String,
			default: '请输入内容……'
		},
		toolbar: {
			type: String,
			default: 'basic'
		},
		height: {
			type: String,
			default: '400px'
		},
		disabled: {
			type: Boolean,
			default: false
		}
	},
	components: {
		Ckeditor
	},
	data(){
		return {
			editorData: '',
			editor: ClassicEditor,
			editorHeight: 0,
			toolbars: {
				full: [
					'sourceEditing', 'undo', 'redo', 'heading', 'style',
					'|', 'superscript', 'subscript', 'removeFormat', 'bold', 'italic', 'underline', 'link', 'fontBackgroundColor', 'fontFamily', 'fontSize', 'fontColor',
					'|', 'outdent', 'indent', 'alignment', 'bulletedList', 'numberedList', 'todoList',
					'|', 'blockQuote', 'insertTable', 'imageInsert', 'mediaEmbed', 'highlight', 'horizontalLine', 'selectAll', 'showBlocks', 'specialCharacters', 'codeBlock', 'findAndReplace'
				],
				basic: [
					'sourceEditing', 'undo', 'redo', 'heading',
					'|', 'removeFormat', 'bold', 'italic', 'underline', 'link', 'fontBackgroundColor', 'fontFamily', 'fontSize', 'fontColor',
					'|', 'outdent', 'indent', 'alignment', 'bulletedList', 'numberedList', 'todoList',
					'|', 'insertTable', 'imageInsert', 'mediaEmbed'
				],
				simple: [
					'sourceEditing', 'heading',
					'|', 'removeFormat', 'bold', 'italic', 'underline', 'link', 'fontBackgroundColor', 'fontFamily', 'fontSize', 'fontColor',
					'|', 'insertTable', 'imageInsert', 'mediaEmbed'
				]
			},
			editorConfig: {
				language: {ui: 'zh-cn', content: 'zh-cn'},
				translations: [ coreTranslations ],
				plugins: [ Alignment, AutoImage, Autoformat, BlockQuote, Bold, CodeBlock, DataFilter, DataSchema, Essentials, FindAndReplace,
					FontBackgroundColor, FontColor, FontFamily, FontSize, GeneralHtmlSupport, Heading, Highlight, HorizontalLine, Image, ImageCaption, ImageInsert, ImageResize,
					ImageStyle, ImageToolbar, ImageUpload, Indent, IndentBlock, Italic, Link, LinkImage, List, MediaEmbed, MediaEmbedToolbar, Mention, Paragraph, PasteFromOffice,
					RemoveFormat, SelectAll, ShowBlocks, SourceEditing, SpecialCharacters, SpecialCharactersArrows, SpecialCharactersCurrency, SpecialCharactersEssentials, SpecialCharactersLatin,
					SpecialCharactersMathematical, SpecialCharactersText, Style, Subscript, Superscript, Table, TableCaption, TableCellProperties, TableColumnResize,
					TableProperties, TableToolbar, TextTransformation, TodoList, Underline, Undo, WordCount, UploadAdapterPlugin
				],
				toolbar: {shouldNotGroupWhenFull: true},
				placeholder: '',
				image: {
					styles: ['alignLeft', 'alignCenter', 'alignRight'],
					toolbar: ['imageTextAlternative', 'toggleImageCaption', '|', 'imageStyle:alignLeft', 'imageStyle:alignCenter', 'imageStyle:alignRight', '|', 'linkImage']
				},
				mediaEmbed: {
					providers: [
						{name: 'mp4', url: /\.(mp4|avi|mov|flv|wmv|mkv)$/i, html: match => {
								const url = match['input']
								return ('<video controls width="100%" height="100%" src="${url}"></video>')
							}
						}
					]
				},
				fontSize: {
					options: [
						10, 12, 14, 16, 18, 20, 22, 24, 26, 30, 32, 36
					]
				},
				style: {
					definitions: [
						{
							name: 'Article category',
							element: 'h3',
							classes: [ 'category' ]
						},
						{
							name: 'Info box',
							element: 'p',
							classes: [ 'info-box' ]
						},
					]
				},
				upload: {
					uploadUrl: this.$API.common.upload.url,
					withCredentials: false,
					extendData: {type: 'images'},
					headers: {
						Authorization: 'Bearer ' + this.$TOOL.data.get('TOKEN')
					}
				},
			}
		}
	},
	watch: {
		modelValue: {
			handler(newVal) {
				this.editorData = newVal ?? ''
			},
			immediate: true,
			deep: true
		},
		placeholder: {
			handler(newVal) {
				this.editorConfig.placeholder = newVal
			},
			immediate: true,
			deep: true
		},
		toolbar: {
			handler(newVal) {
				this.editorConfig.toolbar.items = this.toolbars[newVal]
			},
			immediate: true,
			deep: true
		},
		height: {
			handler(newVal) {
				this.editorHeight = newVal
			},
			immediate: true,
			deep: true
		}
	},
	mounted() {
	},
	methods: {
		onBlur(event, editor) {
			this.editorData = this.editorData.replace(/<img[^>]*>/gi, (match) => {
				return match.replace(/width="[^"]*"/gi, '').replace(/height="[^"]*"/gi, '')
			})
			this.$emit('update:modelValue', this.editorData)
		},
		onFocus(event, editor) {
		}
	}
}
</script>

<style>
:root{
	--ck-z-panel: 9999
}
.ck-content{
	width: 100%;
	height: var(--editor-height);
}
.ck-source-editing-area, .ck-source-editing-area textarea{height: var(--editor-height);}
</style>