Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// This file is part of Moodle - http://moodle.org/
2
//
3
// Moodle is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, either version 3 of the License, or
6
// (at your option) any later version.
7
//
8
// Moodle is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
// GNU General Public License for more details.
12
//
13
// You should have received a copy of the GNU General Public License
14
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
15
 
16
/**
17
 * Tiny Media commands.
18
 *
19
 * @module      tiny_media/commands
20
 * @copyright   2022 Huong Nguyen <huongnv13@gmail.com>
21
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 */
23
 
24
import {getStrings} from 'core/str';
25
import {
26
    component,
27
    imageButtonName,
28
    videoButtonName,
29
    mediaManagerButtonName
30
} from './common';
31
import MediaImage from './image';
32
import MediaEmbed from './embed';
33
import MediaManager from './manager';
34
import {getButtonImage} from 'editor_tiny/utils';
1441 ariadna 35
import Selectors from './selectors';
1 efrain 36
 
37
const isImage = (node) => node.nodeName.toLowerCase() === 'img';
38
const isVideo = (node) => node.nodeName.toLowerCase() === 'video' || node.nodeName.toLowerCase() === 'audio';
39
 
40
const registerImageCommand = (editor, imageButtonText) => {
41
    const imageIcon = 'image';
42
    const handleImageAction = () => {
43
        const mediaImage = new MediaImage(editor);
44
        mediaImage.displayDialogue();
45
    };
46
 
47
    // Register the Menu Button as a toggle.
48
    // This means that when highlighted over an existing Media Image element it will show as toggled on.
49
    editor.ui.registry.addToggleButton(imageButtonName, {
50
        icon: imageIcon,
51
        tooltip: imageButtonText,
52
        onAction: handleImageAction,
53
        onSetup: api => {
54
            return editor.selection.selectorChangedWithUnbind(
55
                'img:not([data-mce-object]):not([data-mce-placeholder]),figure.image',
56
                api.setActive
57
            ).unbind;
58
        }
59
    });
60
 
61
    editor.ui.registry.addMenuItem(imageButtonName, {
62
        icon: imageIcon,
63
        text: imageButtonText,
64
        onAction: handleImageAction,
65
    });
66
 
67
    editor.ui.registry.addContextToolbar(imageButtonName, {
68
        predicate: isImage,
69
        items: imageButtonName,
70
        position: 'node',
71
        scope: 'node'
72
    });
73
 
74
    editor.ui.registry.addContextMenu(imageButtonName, {
75
        update: isImage,
76
    });
1441 ariadna 77
 
78
    // Let's check for image file at dragged and dropped and add img-fluid class if it does't have it yet.
79
    editor.on('SetContent', function() {
80
        const imgs = editor.getBody().querySelectorAll(`img:not(.${Selectors.IMAGE.styles.responsive})`);
81
        imgs.forEach(img => img.classList.add(`${Selectors.IMAGE.styles.responsive}`));
82
    });
1 efrain 83
};
84
 
85
const registerEmbedCommand = (editor, videoButtonText) => {
86
    const videoIcon = 'embed';
87
    const handleEmbedAction = () => {
88
        const mediaImage = new MediaEmbed(editor);
89
        mediaImage.displayDialogue();
90
    };
91
 
92
    // Register the Menu Button as a toggle.
93
    // This means that when highlighted over an existing Media Video element it will show as toggled on.
94
    editor.ui.registry.addToggleButton(videoButtonName, {
95
        icon: videoIcon,
96
        tooltip: videoButtonText,
97
        onAction: handleEmbedAction,
98
        onSetup: api => {
99
            return editor.selection.selectorChangedWithUnbind(
100
                'video:not([data-mce-object]):not([data-mce-placeholder]),' +
1441 ariadna 101
                'audio:not([data-mce-object]):not([data-mce-placeholder]),' +
102
                'a:not([data-mce-object]):not([data-mce-placeholder])[class=external-media-provider]',
1 efrain 103
                api.setActive
104
            ).unbind;
105
        }
106
    });
107
 
108
    editor.ui.registry.addMenuItem(videoButtonName, {
109
        icon: videoIcon,
110
        text: videoButtonText,
111
        onAction: handleEmbedAction,
112
    });
113
 
114
    editor.ui.registry.addContextMenu(videoButtonName, {
115
        update: isVideo,
116
    });
117
 
118
    editor.ui.registry.addContextToolbar(videoButtonName, {
119
        predicate: isVideo,
120
        items: videoButtonName,
121
        position: 'node',
122
        scope: 'node'
123
    });
124
 
125
};
126
 
127
const registerManagerCommand = (editor, mediaManagerButtonText, mediaManagerButtonImage) => {
128
    const mediaManagerIcon = 'filemanager';
129
    const handleMediaManager = () => {
130
        const mediaManager = new MediaManager(editor);
131
        mediaManager.displayDialogue();
132
    };
133
 
134
    // Register the Menu Button as a toggle.
135
    editor.ui.registry.addIcon(mediaManagerIcon, mediaManagerButtonImage.html);
136
    editor.ui.registry.addButton(mediaManagerButtonName, {
137
        icon: mediaManagerIcon,
138
        tooltip: mediaManagerButtonText,
139
        onAction: () => {
140
            handleMediaManager();
141
        }
142
    });
143
 
144
    editor.ui.registry.addMenuItem(mediaManagerButtonName, {
145
        icon: mediaManagerIcon,
146
        text: mediaManagerButtonText,
147
        onAction: () => {
148
            handleMediaManager();
149
        }
150
    });
151
};
152
 
153
export const getSetup = async() => {
154
    const [
155
        imageButtonText,
156
        mediaButtonText,
157
        mediaManagerButtonText
158
    ] = await getStrings(['imagebuttontitle', 'mediabuttontitle', 'mediamanagerbuttontitle'].map((key) => ({key, component})));
159
 
160
    const [
161
        mediaManagerButtonImage,
162
    ] = await Promise.all([
163
        getButtonImage('filemanager', component)
164
    ]);
165
 
166
    // Note: The function returned here must be synchronous and cannot use promises.
167
    // All promises must be resolved prior to returning the function.
168
    return (editor) => {
169
        registerImageCommand(editor, imageButtonText);
170
        registerEmbedCommand(editor, mediaButtonText);
171
        registerManagerCommand(editor, mediaManagerButtonText, mediaManagerButtonImage);
172
    };
173
};