aboutsummaryrefslogtreecommitdiff
path: root/resources/vue/components/courseware/blocks/CoursewareTextBlock.vue
blob: dd8bd74aaa9e650c0690ad74c16a2c49c95e5336 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<template>
    <div class="cw-block cw-block-text">
        <courseware-default-block
            :block="block"
            :canEdit="canEdit"
            :isTeacher="isTeacher"
            :preview="false"
            ref="defaultBlock"
            @showEdit="initCurrent"
            @storeEdit="storeText"
            @closeEdit="initCurrent"
        >
            <template #content>
                <section class="formatted-content ck-content" v-html="currentText" ref="content"></section>
            </template>
            <template v-if="canEdit" #edit>
                <div ref="ckeditor">
                    <ckeditor :editor="editor" v-model="currentText" :config="editorConfig" @ready="onReady"></ckeditor>
                </div>
            </template>
            <template #info>{{ $gettext('Informationen zum Text-Block') }}</template>
        </courseware-default-block>
    </div>
</template>

<script>
import BlockComponents from './block-components.js';
import blockMixin from '@/vue/mixins/courseware/block.js';
import FindAndReplace from '@ckeditor/ckeditor5-find-and-replace/src/findandreplace';
import { ClassicEditor } from '@/assets/javascripts/chunks/wysiwyg';
import { mapActions } from 'vuex';

export default {
    name: 'courseware-text-block',
    mixins: [blockMixin],
    components: Object.assign(BlockComponents, {}),
    props: {
        block: Object,
        canEdit: Boolean,
        isTeacher: Boolean,
    },
    data() {
        return {
            currentText: '',
            editor: ClassicEditor,
            editorConfig: {
                // The configuration of the editor.
                extraPlugins: [FindAndReplace],
            },
        };
    },
    computed: {
        text() {
            return this.block?.attributes?.payload?.text;
        },
        ckeToolbarTop() {
            const topBar = document.getElementById('top-bar');
            const responsiveContentbar = document.getElementById('responsive-contentbar');
            let top = topBar.clientHeight + topBar.clientTop;
            if (responsiveContentbar) {
                top += responsiveContentbar?.clientHeight + responsiveContentbar?.clientTop;
            } else {
                top += 85;
            }

            return top;
        },
    },
    mounted() {
        this.initCurrent();
    },
    methods: {
        ...mapActions({
            updateBlock: 'updateBlockInContainer',
        }),
        initCurrent() {
            this.currentText = this.text;
            this.loadMathjax();

            window.addEventListener('resize', this.fixPanelSize);
        },
        onReady(editor) {
            editor.ui.viewportOffset = { top: this.ckeToolbarTop };
            editor.ui.update();
            this.fixPanelSize();
        },
        async storeText() {
            let attributes = this.block.attributes;
            attributes.payload.text = this.currentText;
            await this.updateBlock({
                attributes: attributes,
                blockId: this.block.id,
                containerId: this.block.relationships.container.data.id,
            });
            this.$refs.defaultBlock.displayFeature(false);
            this.loadMathjax();
        },
        loadMathjax() {
            let mathjaxP;

            if (window.MathJax && window.MathJax.Hub) {
                mathjaxP = Promise.resolve(window.MathJax);
            } else if (window.STUDIP && window.STUDIP.loadChunk) {
                mathjaxP = window.STUDIP.loadChunk('mathjax');
            }

            if (mathjaxP) {
                mathjaxP
                    .then(({Hub}) => {
                        Hub.Queue(['Typeset', Hub, this.$refs.content]);
                    })
                    .catch(() => {
                        console.log('Warning: Could not load MathJax.');
                    });
            }
        },
        fixPanelSize() {
            const ckeElement = this.$refs.ckeditor.querySelector('.ck-editor');
            const dropdownPanel = ckeElement?.querySelector('.ck-toolbar__grouped-dropdown .ck-dropdown__panel');
            if (dropdownPanel) {
                dropdownPanel.style.maxWidth = `${ckeElement.clientWidth}px`;
            }
        }
    },
};
</script>
<style scoped lang="scss">
@import '../../../../assets/stylesheets/scss/courseware/blocks/text';
</style>