ldc-loue/resources/ts/components/bo/CkEditorBoComponent.vue
2022-06-12 16:38:22 +02:00

221 lines
5.9 KiB
Vue

<template>
<div>
<div ref="wordCounter"></div>
<div ref="ckeditor"></div>
<input
:id="internalId"
class="form-control"
type="hidden"
:name="name"
:value="internalText"
:required="internalRequired"
/>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
import trans from "../../modules/trans";
import "./../../../js/vendor/ckeditor/build/ckeditor";
export default defineComponent({
mixins: [trans],
beforeMount() {
if (!this.$attrs.json) {
throw new Error("this component requires json");
}
},
mounted() {
const json = String(this.$attrs.json ?? ""),
data = JSON.parse(json);
this.name = data.name;
this.internalText = data.text;
this.internalId = data.id ? data.id : "";
this.internalRequired = Boolean(data.required);
this.makeSuperBuild();
},
data(): {
name: string;
internalText: string;
internalId: string;
internalRequired: boolean;
// @ts-ignore
editor: ClassicEditor | null;
words: number;
chars: number;
} {
return {
name: "",
internalText: "",
internalId: "",
internalRequired: false,
editor: null,
words: 0,
chars: 0,
};
},
watch: {
dbtext() {
if (this.internalText != this.dbtext) {
this.internalText = this.dbtext;
if (this.editor) {
this.editor.setData(this.internalText);
}
}
},
},
methods: {
makeSuperBuild() {
const self = this,
ckeditor = this.$refs.ckeditor as HTMLElement,
wordCounter = this.$refs.wordCounter as HTMLElement;
// @ts-ignore
ClassicEditor.create(ckeditor, {
wordCount: {
container: wordCounter,
// @ts-ignore
onUpdate: (stats) => {
this.chars = stats.characters;
this.words = stats.words;
},
},
mediaEmbed: {
previewsInData: false,
removeProviders: [
"instagram",
"twitter",
"googleMaps",
"flickr",
"facebook",
"dailymotion",
"spotify",
],
// see https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-media-embed/src/mediaembedediting.js
// providers: ['youtube', {
// // display local videos in oembed tags
// name: 'localVideo',
// url: /^(\/(?:content|storage)\/.*)/,
// html: match => {
// let path = match[ 1 ];
// return (
// '<video controls allowfullscreen style="max-width: 90%; margin: 0 auto; display: block;">' +
// `<source src="${ path }" type="video/mp4">` +
// `<p>Votre navigateur ne prend pas en charge les vidéos HTML5. Voici <a href="${ path }">un lien pour télécharger la vidéo</a>.</p>` +
// '</video>'
// );
// }
// }]
},
toolbar: {
items: [
"heading",
"|",
"bold",
"italic",
"underline",
"link",
"bulletedList",
"numberedList",
"|",
"outdent",
"indent",
"alignment",
"|",
"undo",
"redo",
"|",
"laravelFileManager",
"mediaEmbed",
"blockQuote",
"|",
// 'insertImage', 'mediaEmbed', 'blockQuote','|',
"insertTable",
"tableColumn",
"tableRow",
"mergeTableCells",
"|",
// 'videoStyle:alignLeft', 'videoStyle:alignCenter', 'videoStyle:alignRight', 'videoResize',
// '|',
// 'videoResize:50',
// 'videoResize:75',
// 'videoResize:original',
"fontColor",
"fontFamily",
"fontSize",
"horizontalLine",
"|",
"removeFormat",
"|",
"undo",
"redo",
"|",
"sourceEditing",
],
},
table: {
contentToolbar: [
"tableColumn",
"tableRow",
"mergeTableCells",
"tableProperties",
"tableCellProperties",
"toggleTableCaption",
],
},
language: "fr",
image: {
toolbar: [
"imageTextAlternative",
"imageStyle:inline",
"imageStyle:block",
"imageStyle:side",
"linkImage",
],
},
})
// @ts-ignore
.then((editor: ClassicEditor) => {
self.editor = editor;
editor.setData(this.internalText);
editor.model.document.on("change:data", () => {
// * Keep track of internal editor
let data = editor.getData();
self.internalText = data;
self.$emit("input", data);
});
})
// @ts-ignore
.catch((error) => {
console.error("Oops, something went wrong!");
console.error(
"Please, report the following error on https://github.com/ckeditor/ckeditor5/issues with the build id and the error stack trace:"
);
console.warn("Build id: x0tjc6omqq4d-iydt761tuj51");
console.error(error);
});
},
},
});
</script>
<style lang="scss">
@import url("./../../../js/vendor/ckeditor/build/styles.css");
.ck-word-count {
display: flex;
flex-direction: column;
color: initial;
border: 1px solid rgb(196, 196, 196);
border-bottom: 0;
background-color: #fafafa;
position: relative;
.ck-word-count__words {
position: relative;
left: 2rem;
}
.ck-word-count__characters {
position: absolute;
left: 9rem;
}
}
</style>