| 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 plugin Embed class for Moodle.
|
|
|
18 |
*
|
|
|
19 |
* @module tiny_media/embed
|
|
|
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 EmbedModal from './embedmodal';
|
|
|
25 |
import {getEmbedPermissions} from './options';
|
| 1441 |
ariadna |
26 |
import {getFilePicker, getContextId} from 'editor_tiny/options';
|
|
|
27 |
import {EmbedHandler} from './embed/embedhandler';
|
|
|
28 |
import {insertMediaTemplateContext, getSelectedMediaElement} from './embed/embedhelpers';
|
|
|
29 |
import {EmbedInsert} from './embed/embedinsert';
|
|
|
30 |
import {startMediaLoading} from './helpers';
|
|
|
31 |
import Selectors from "./selectors";
|
| 1 |
efrain |
32 |
|
|
|
33 |
export default class MediaEmbed {
|
|
|
34 |
editor = null;
|
|
|
35 |
canShowFilePicker = false;
|
|
|
36 |
canShowFilePickerTrack = false;
|
| 1441 |
ariadna |
37 |
canShowDropZone = false;
|
| 1 |
efrain |
38 |
|
|
|
39 |
constructor(editor) {
|
|
|
40 |
const permissions = getEmbedPermissions(editor);
|
| 1441 |
ariadna |
41 |
const options = getFilePicker(editor, 'media');
|
| 1 |
efrain |
42 |
|
|
|
43 |
// Indicates whether the file picker can be shown.
|
| 1441 |
ariadna |
44 |
this.canShowFilePicker = permissions.filepicker
|
|
|
45 |
&& (typeof options !== 'undefined')
|
|
|
46 |
&& Object.keys(options.repositories).length > 0;
|
| 1 |
efrain |
47 |
this.canShowFilePickerTrack = permissions.filepicker && (typeof getFilePicker(editor, 'subtitle') !== 'undefined');
|
| 1441 |
ariadna |
48 |
this.canShowDropZone = Object.values(options.repositories).some(repository => repository.type === 'upload');
|
|
|
49 |
this.editor = editor;
|
|
|
50 |
this.acceptedMediaTypes = options.accepted_types;
|
|
|
51 |
this.contextId = getContextId(editor);
|
| 1 |
efrain |
52 |
|
| 1441 |
ariadna |
53 |
// Image options.
|
|
|
54 |
const imageOptions = getFilePicker(editor, 'image');
|
|
|
55 |
this.acceptedImageTypes = imageOptions.accepted_types;
|
|
|
56 |
this.canShowImageFilePicker = permissions.filepicker
|
|
|
57 |
&& (typeof imageOptions !== 'undefined')
|
|
|
58 |
&& Object.keys(imageOptions.repositories).length > 0;
|
| 1 |
efrain |
59 |
}
|
|
|
60 |
|
| 1441 |
ariadna |
61 |
/**
|
|
|
62 |
* Displays media modal accordingly.
|
|
|
63 |
*/
|
|
|
64 |
displayDialogue = async() => {
|
|
|
65 |
const [mediaType, selectedMedia] = getSelectedMediaElement(this.editor);
|
|
|
66 |
this.mediaType = mediaType;
|
|
|
67 |
this.selectedMedia = selectedMedia;
|
| 1 |
efrain |
68 |
|
| 1441 |
ariadna |
69 |
if (this.selectedMedia) {
|
|
|
70 |
// Preview the selected media.
|
|
|
71 |
this.isUpdating = true;
|
|
|
72 |
this.loadSelectedMedia();
|
|
|
73 |
} else {
|
|
|
74 |
// Create media modal.
|
|
|
75 |
await this.createMediaModal();
|
|
|
76 |
// Load insert media modal.
|
|
|
77 |
await this.loadInsertMediaModal();
|
| 1 |
efrain |
78 |
}
|
| 1441 |
ariadna |
79 |
};
|
| 1 |
efrain |
80 |
|
| 1441 |
ariadna |
81 |
/**
|
|
|
82 |
* Load insert media modal.
|
|
|
83 |
*/
|
|
|
84 |
loadInsertMediaModal = async() => {
|
|
|
85 |
const embedHandler = new EmbedHandler(this);
|
|
|
86 |
embedHandler.loadTemplatePromise(insertMediaTemplateContext(this));
|
|
|
87 |
await embedHandler.registerEventListeners();
|
|
|
88 |
};
|
| 1 |
efrain |
89 |
|
| 1441 |
ariadna |
90 |
/**
|
|
|
91 |
* Create media modal.
|
|
|
92 |
*/
|
|
|
93 |
createMediaModal = async() => {
|
| 1 |
efrain |
94 |
this.currentModal = await EmbedModal.create({
|
| 1441 |
ariadna |
95 |
large: true,
|
|
|
96 |
templateContext: {elementid: this.editor.getElement().id},
|
| 1 |
efrain |
97 |
});
|
| 1441 |
ariadna |
98 |
this.modalRoot = this.currentModal.getRoot();
|
|
|
99 |
this.root = this.modalRoot[0];
|
|
|
100 |
};
|
| 1 |
efrain |
101 |
|
| 1441 |
ariadna |
102 |
/**
|
|
|
103 |
* Load media preview based on the selected media.
|
|
|
104 |
*/
|
|
|
105 |
loadSelectedMedia = async() => {
|
|
|
106 |
let mediaSource = null;
|
|
|
107 |
if (['video', 'audio'].includes(this.mediaType)) {
|
|
|
108 |
mediaSource = this.selectedMedia.querySelector('source').src;
|
|
|
109 |
// If the selected media has more than one sources, it has main source and alternative sources.
|
|
|
110 |
const sources = this.selectedMedia.querySelectorAll('source');
|
|
|
111 |
if (sources.length > 1) {
|
|
|
112 |
let alternativeSources = [];
|
|
|
113 |
Object.keys(sources).forEach(function(source) {
|
|
|
114 |
alternativeSources.push(sources[source].src);
|
|
|
115 |
});
|
|
|
116 |
this.alternativeSources = alternativeSources; // Used to later check if the embedded media has alternative sources.
|
| 1 |
efrain |
117 |
}
|
| 1441 |
ariadna |
118 |
} else if (this.selectedMedia.classList.contains(Selectors.EMBED.externalMediaProvider)) {
|
|
|
119 |
mediaSource = this.selectedMedia.href;
|
|
|
120 |
this.mediaType = 'link';
|
| 1 |
efrain |
121 |
}
|
|
|
122 |
|
| 1441 |
ariadna |
123 |
// Load media preview.
|
|
|
124 |
if (this.mediaType) {
|
|
|
125 |
// Create media modal.
|
|
|
126 |
await this.createMediaModal();
|
|
|
127 |
// Start the spinner.
|
|
|
128 |
startMediaLoading(this.root, Selectors.EMBED.type);
|
| 1 |
efrain |
129 |
|
| 1441 |
ariadna |
130 |
const embedInsert = new EmbedInsert(this);
|
|
|
131 |
embedInsert.init();
|
|
|
132 |
embedInsert.loadMediaPreview(mediaSource);
|
|
|
133 |
await (new EmbedHandler(this)).registerEventListeners();
|
|
|
134 |
} else {
|
|
|
135 |
// Create media modal.
|
|
|
136 |
await this.createMediaModal();
|
|
|
137 |
// Load insert media modal.
|
|
|
138 |
this.loadInsertMediaModal();
|
| 1 |
efrain |
139 |
}
|
| 1441 |
ariadna |
140 |
};
|
| 1 |
efrain |
141 |
}
|