MDL-78428 tiny_media: Handled save-update media
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -7,6 +7,6 @@ define("tiny_media/embed/embedhelpers",["exports","../selectors","../helpers","c
|
||||
* @module tiny_media/embed/embedhelpers
|
||||
* @copyright 2024 Stevani Andolo <stevani@hotmail.com.au>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.prepareMoodleLang=_exports.mediaDetailsTemplateContext=_exports.isUrlFromKnownMediaSites=_exports.insertMediaTemplateContext=_exports.getSelectedMediaElement=_exports.getMoodleLangObj=_exports.getHelpStrings=_exports.getEmbeddedMediaDetails=_exports.formatMediaUrl=void 0,_selectors=(obj=_selectors)&&obj.__esModule?obj:{default:obj};_exports.insertMediaTemplateContext=props=>({mediaType:props.mediaType,showDropzone:props.canShowDropZone,showFilePicker:props.canShowFilePicker});_exports.getSelectedMediaElement=editor=>{let mediaType=null,selectedMedia=null;const mediaElm=editor.selection.getNode();return mediaElm?"video"===mediaElm.nodeName.toLowerCase()||"audio"===mediaElm.nodeName.toLowerCase()?(mediaType=mediaElm.nodeName.toLowerCase(),selectedMedia=mediaElm):"a"===mediaElm.nodeName.toLowerCase()?(mediaType="link",selectedMedia=mediaElm):mediaElm.querySelector("video")?(mediaType="video",selectedMedia=mediaElm.querySelector("video")):mediaElm.querySelector("audio")&&(mediaType="audio",selectedMedia=mediaElm.querySelector("audio")):(mediaType=null,selectedMedia=null),[mediaType,selectedMedia]};_exports.formatMediaUrl=url=>{const params=(0,_helpers.convertStringUrlToObject)(url);if(url.includes(_selectors.default.EMBED.mediaSites.youtube)){let fetchedUrl=null,fetchedUrlValue=null;for(const k in params)if(url.includes(k)){fetchedUrl=k,fetchedUrlValue=params[k],delete params[k];break}url=(url=fetchedUrl.replace("watch?v","embed/"))+fetchedUrlValue+"?"+(0,_helpers.createUrlParams)(params)}return url};_exports.isUrlFromKnownMediaSites=url=>{let state=!1;const sites=_selectors.default.EMBED.mediaSites;for(const site in sites)if(url.includes(sites[site])){state=!0;break}return state};_exports.mediaDetailsTemplateContext=async props=>{const context={bodyTemplate:_selectors.default.EMBED.template.body.mediaDetailsBody,footerTemplate:_selectors.default.EMBED.template.footer.mediaDetailsFooter,isVideo:"video"===props.mediaType,isAudio:"audio"===props.mediaType,isLink:"link"===props.mediaType,isUpdating:props.isUpdating};return props.mediaData?{...context,...props.mediaData}:{...context,...await props.mediaTemplateContext}};_exports.getHelpStrings=async()=>{const[customsize]=await(0,_str.getStrings)(["customsize_help"].map((key=>({key:key,component:_common.component}))));return{customsize:customsize}};_exports.prepareMoodleLang=editor=>{const moodleLangs=(0,_options.getMoodleLang)(editor),currentLanguage=(0,_options.getCurrentLanguage)(editor);return{installed:Object.entries(moodleLangs.installed).map((_ref=>{let[lang,code]=_ref;return{lang:lang,code:code,default:lang===currentLanguage}})),available:Object.entries(moodleLangs.available).map((_ref2=>{let[lang,code]=_ref2;return{lang:lang,code:code,default:lang===currentLanguage}}))}};_exports.getMoodleLangObj=(subtitleLang,editor)=>{const{available:available}=(0,_options.getMoodleLang)(editor);return available[subtitleLang]?{lang:subtitleLang,code:available[subtitleLang]}:null};_exports.getEmbeddedMediaDetails=props=>{const tracks={subtitles:[],captions:[],descriptions:[],chapters:[],metadata:[]};props.root.querySelectorAll(_selectors.default.EMBED.elements.mediaMetadataTabPane).forEach((metaData=>{metaData.querySelectorAll(_selectors.default.EMBED.elements.track).forEach((track=>{tracks[metaData.dataset.trackKind].push({src:track.querySelector(_selectors.default.EMBED.elements.url).value,srclang:track.querySelector(_selectors.default.EMBED.elements.trackLang).value,label:track.querySelector(_selectors.default.EMBED.elements.trackLabel).value,defaultTrack:track.querySelector(_selectors.default.EMBED.elements.trackDefault).checked})}))}));const querySelector=element=>props.root.querySelector(element),mediaDataProps={};return mediaDataProps.media={type:props.mediaType,sources:props.media,poster:querySelector(_selectors.default.EMBED.elements.videoTag).getAttribute("poster"),title:querySelector(_selectors.default.EMBED.elements.title).value,width:querySelector(_selectors.default.EMBED.elements.width).value,height:querySelector(_selectors.default.EMBED.elements.height).value,autoplay:querySelector(_selectors.default.EMBED.elements.mediaAutoplay).checked,loop:querySelector(_selectors.default.EMBED.elements.mediaLoop).checked,muted:querySelector(_selectors.default.EMBED.elements.mediaMute).checked,controls:querySelector(_selectors.default.EMBED.elements.mediaControl).checked,tracks:tracks},mediaDataProps.link=!1,mediaDataProps}}));
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.prepareMoodleLang=_exports.mediaDetailsTemplateContext=_exports.isUrlFromKnownMediaSites=_exports.insertMediaTemplateContext=_exports.getSelectedMediaElement=_exports.getMoodleLangObj=_exports.getLinkBasedUrl=_exports.getHelpStrings=_exports.getEmbeddedMediaDetails=_exports.formatMediaUrl=void 0,_selectors=(obj=_selectors)&&obj.__esModule?obj:{default:obj};_exports.insertMediaTemplateContext=props=>({mediaType:props.mediaType,showDropzone:props.canShowDropZone,showFilePicker:props.canShowFilePicker});_exports.getSelectedMediaElement=editor=>{let mediaType=null,selectedMedia=null;const mediaElm=editor.selection.getNode();return mediaElm?"video"===mediaElm.nodeName.toLowerCase()||"audio"===mediaElm.nodeName.toLowerCase()?(mediaType=mediaElm.nodeName.toLowerCase(),selectedMedia=mediaElm):"a"===mediaElm.nodeName.toLowerCase()?(mediaType="link",selectedMedia=mediaElm):mediaElm.querySelector("video")?(mediaType="video",selectedMedia=mediaElm.querySelector("video")):mediaElm.querySelector("audio")&&(mediaType="audio",selectedMedia=mediaElm.querySelector("audio")):(mediaType=null,selectedMedia=null),[mediaType,selectedMedia]};_exports.formatMediaUrl=url=>{const params=(0,_helpers.convertStringUrlToObject)(url);if(url.includes(_selectors.default.EMBED.mediaSites.youtube)){let fetchedUrl=null,fetchedUrlValue=null;for(const k in params)if(url.includes(k)){fetchedUrl=k,fetchedUrlValue=params[k],delete params[k];break}url=(url=fetchedUrl.replace("watch?v","embed/"))+fetchedUrlValue+"?"+(0,_helpers.createUrlParams)(params)}return url};_exports.isUrlFromKnownMediaSites=url=>{let state=!1;const sites=_selectors.default.EMBED.mediaSites;for(const site in sites)if(url.includes(sites[site])){state=!0;break}return state};_exports.mediaDetailsTemplateContext=async props=>{const context={bodyTemplate:_selectors.default.EMBED.template.body.mediaDetailsBody,footerTemplate:_selectors.default.EMBED.template.footer.mediaDetailsFooter,isVideo:"video"===props.mediaType,isAudio:"audio"===props.mediaType,isLink:"link"===props.mediaType,isUpdating:props.isUpdating};return props.mediaData?{...context,...props.mediaData}:{...context,...await props.mediaTemplateContext}};_exports.getHelpStrings=async()=>{const[customsize]=await(0,_str.getStrings)(["customsize_help"].map((key=>({key:key,component:_common.component}))));return{customsize:customsize}};_exports.prepareMoodleLang=editor=>{const moodleLangs=(0,_options.getMoodleLang)(editor),currentLanguage=(0,_options.getCurrentLanguage)(editor);return{installed:Object.entries(moodleLangs.installed).map((_ref=>{let[lang,code]=_ref;return{lang:lang,code:code,default:lang===currentLanguage}})),available:Object.entries(moodleLangs.available).map((_ref2=>{let[lang,code]=_ref2;return{lang:lang,code:code,default:lang===currentLanguage}}))}};_exports.getMoodleLangObj=(subtitleLang,editor)=>{const{available:available}=(0,_options.getMoodleLang)(editor);return available[subtitleLang]?{lang:subtitleLang,code:available[subtitleLang]}:null};_exports.getEmbeddedMediaDetails=props=>{const tracks={subtitles:[],captions:[],descriptions:[],chapters:[],metadata:[]};props.root.querySelectorAll(_selectors.default.EMBED.elements.mediaMetadataTabPane).forEach((metaData=>{metaData.querySelectorAll(_selectors.default.EMBED.elements.track).forEach((track=>{tracks[metaData.dataset.trackKind].push({src:track.querySelector(_selectors.default.EMBED.elements.url).value,srclang:track.querySelector(_selectors.default.EMBED.elements.trackLang).value,label:track.querySelector(_selectors.default.EMBED.elements.trackLabel).value,defaultTrack:track.querySelector(_selectors.default.EMBED.elements.trackDefault).checked})}))}));const querySelector=element=>props.root.querySelector(element),mediaDataProps={};return mediaDataProps.media={type:props.mediaType,sources:props.media,poster:querySelector(_selectors.default.EMBED.elements.videoTag).getAttribute("poster"),title:querySelector(_selectors.default.EMBED.elements.title).value,width:querySelector(_selectors.default.EMBED.elements.width).value,height:querySelector(_selectors.default.EMBED.elements.height).value,autoplay:querySelector(_selectors.default.EMBED.elements.mediaAutoplay).checked,loop:querySelector(_selectors.default.EMBED.elements.mediaLoop).checked,muted:querySelector(_selectors.default.EMBED.elements.mediaMute).checked,controls:querySelector(_selectors.default.EMBED.elements.mediaControl).checked,tracks:tracks},mediaDataProps.link=!1,mediaDataProps};_exports.getLinkBasedUrl=url=>{if(url.includes(_selectors.default.EMBED.mediaSites.youtube)&&url.includes("embed/")){const urlParams=url.split("embed/");let id=null;id=urlParams[1].includes("?")?urlParams[1].split("?")[0]:urlParams[1],url="".concat(urlParams[0],"watch?v=").concat(id,"&")}return url}}));
|
||||
|
||||
//# sourceMappingURL=embedhelpers.min.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -39,6 +39,7 @@ import {
|
||||
isValidUrl,
|
||||
convertStringUrlToObject,
|
||||
stopMediaLoading,
|
||||
createUrlParams,
|
||||
} from '../helpers';
|
||||
import * as ModalEvents from 'core/modal_events';
|
||||
import {displayFilepicker} from 'editor_tiny/utils';
|
||||
@@ -47,7 +48,9 @@ import {
|
||||
getHelpStrings,
|
||||
prepareMoodleLang,
|
||||
getMoodleLangObj,
|
||||
getLinkBasedUrl,
|
||||
} from "./embedhelpers";
|
||||
import Templates from 'core/templates';
|
||||
|
||||
export class EmbedHandler {
|
||||
|
||||
@@ -413,6 +416,119 @@ export class EmbedHandler {
|
||||
addUrl.disabled = !(url !== "" && isValidUrl(url));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get media html to be inserted or updated into tiny.
|
||||
*
|
||||
* @param {html} form Selected element
|
||||
* @returns {string} String of html
|
||||
*/
|
||||
getMediaHTML = (form) => {
|
||||
let mediumType = this.root.querySelector(Selectors.EMBED.elements.previewClass).nodeName.toLowerCase();
|
||||
mediumType = (mediumType === 'iframe') ? 'link' : mediumType;
|
||||
const tabContent = form.querySelector('.tab-content');
|
||||
const callback = 'getMediaHTML' + mediumType[0].toUpperCase() + mediumType.substr(1);
|
||||
return this[callback](tabContent);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get media as link.
|
||||
*
|
||||
* @returns {string} String of html
|
||||
*/
|
||||
getMediaHTMLLink = () => {
|
||||
const details = document.querySelector(Selectors.EMBED.elements.mediaDetailsBody);
|
||||
const url = details.querySelector(Selectors.EMBED.elements.preview).src ?? null;
|
||||
const urlParamString = createUrlParams({
|
||||
controls: details.querySelector(Selectors.EMBED.elements.mediaControl).checked ? 1 : 0,
|
||||
autoplay: details.querySelector(Selectors.EMBED.elements.mediaAutoplay).checked ? 1 : 0,
|
||||
mute: details.querySelector(Selectors.EMBED.elements.mediaMute).checked ? 1 : 0,
|
||||
});
|
||||
const name = details.querySelector(Selectors.EMBED.elements.title).value || false;
|
||||
const context = {
|
||||
url: getLinkBasedUrl(url) + urlParamString,
|
||||
name: name ? name.trim() : false,
|
||||
};
|
||||
|
||||
return context.url ? Templates.renderForPromise('tiny_media/embed/embed_media_link', context) : '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get media as video.
|
||||
*
|
||||
* @param {html} tab Selected element
|
||||
* @returns {string} String of html.
|
||||
*/
|
||||
getMediaHTMLVideo = (tab) => {
|
||||
const details = document.querySelector(Selectors.EMBED.elements.mediaDetailsBody);
|
||||
const context = this.getContextForMediaHTML(tab, details);
|
||||
context.width = details.querySelector(Selectors.EMBED.elements.width).value || false;
|
||||
context.height = details.querySelector(Selectors.EMBED.elements.height).value || false;
|
||||
context.poster = details.querySelector(Selectors.EMBED.elements.videoTag).poster || false;
|
||||
return context.sources ? Templates.renderForPromise('tiny_media/embed/embed_media_video', context) : '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get media as audio.
|
||||
*
|
||||
* @param {html} tab Selected element
|
||||
* @returns {string} String of html.
|
||||
*/
|
||||
getMediaHTMLAudio = (tab) => {
|
||||
const details = document.querySelector(Selectors.EMBED.elements.mediaDetailsBody);
|
||||
const context = this.getContextForMediaHTML(tab, details);
|
||||
return context.sources.length ? Templates.renderForPromise('tiny_media/embed/embed_media_audio', context) : '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get previewed media data.
|
||||
*
|
||||
* @param {html} tab Selected element
|
||||
* @param {html} details Selected element
|
||||
* @returns {object}
|
||||
*/
|
||||
getContextForMediaHTML = (tab, details) => {
|
||||
const tracks = Array.from(tab.querySelectorAll(Selectors.EMBED.elements.track)).map(track => ({
|
||||
track: track.querySelector(Selectors.EMBED.elements.trackSource + ' ' + Selectors.EMBED.elements.url).value,
|
||||
kind: this.getTrackTypeFromTabPane(track.closest('.tab-pane')),
|
||||
label: track.querySelector(Selectors.EMBED.elements.trackLabel).value ||
|
||||
track.querySelector(Selectors.EMBED.elements.trackLang).value,
|
||||
srclang: track.querySelector(Selectors.EMBED.elements.trackLang).value,
|
||||
defaultTrack: track.querySelector(Selectors.EMBED.elements.trackDefault).checked ? "true" : null
|
||||
})).filter((track) => !!track.track);
|
||||
|
||||
const sources = details.querySelector(Selectors.EMBED.elements.preview).src ?? null;
|
||||
const title = details.querySelector(Selectors.EMBED.elements.title).value;
|
||||
|
||||
return {
|
||||
sources,
|
||||
description: tab.querySelector(Selectors.EMBED.elements.url).value || false,
|
||||
tracks,
|
||||
showControls: details.querySelector(Selectors.EMBED.elements.mediaControl).checked,
|
||||
autoplay: details.querySelector(Selectors.EMBED.elements.mediaAutoplay).checked,
|
||||
muted: details.querySelector(Selectors.EMBED.elements.mediaMute).checked,
|
||||
loop: details.querySelector(Selectors.EMBED.elements.mediaLoop).checked,
|
||||
title: title !== '' ? title.trim() : false,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle the insert/update media in tiny editor.
|
||||
*
|
||||
* @param {event} event
|
||||
* @param {object} modal Object of current modal
|
||||
*/
|
||||
handleDialogueSubmission = async(event, modal) => {
|
||||
const {html} = await this.getMediaHTML(modal.getRoot()[0]);
|
||||
if (html) {
|
||||
if (this.isUpdating) {
|
||||
this.selectedMedia.outerHTML = html;
|
||||
this.isUpdating = false;
|
||||
} else {
|
||||
this.editor.insertContent(html);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
registerEventListeners = async(modal) => {
|
||||
await modal.getBody();
|
||||
const $root = modal.getRoot();
|
||||
@@ -440,5 +556,7 @@ export class EmbedHandler {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$root.on(ModalEvents.save, this.handleDialogueSubmission.bind(this));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -269,3 +269,25 @@ export const getEmbeddedMediaDetails = (props) => {
|
||||
mediaDataProps.link = false;
|
||||
return mediaDataProps;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get based url from the link.
|
||||
*
|
||||
* @param {string} url
|
||||
* @returns {string}
|
||||
*/
|
||||
export const getLinkBasedUrl = (url) => {
|
||||
if (url.includes(Selectors.EMBED.mediaSites.youtube)) {
|
||||
if (url.includes('embed/')) {
|
||||
const urlParams = url.split('embed/');
|
||||
let id = null;
|
||||
if (urlParams[1].includes('?')) {
|
||||
id = urlParams[1].split('?')[0];
|
||||
} else {
|
||||
id = urlParams[1];
|
||||
}
|
||||
url = `${urlParams[0]}watch?v=${id}&`;
|
||||
}
|
||||
}
|
||||
return url;
|
||||
};
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
</div>
|
||||
<div class="col-md-6 text-right mt-2 md-0 p-0">
|
||||
<button type="button" class="btn btn-secondary" data-action="back-to-media-details">{{#str}} back, tiny_media {{/str}}</button>
|
||||
<button class="tiny_media_submit btn btn-primary" data-action="save">
|
||||
{{#str}} saveimage, tiny_media {{/str}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{/isLink}}
|
||||
|
||||
Reference in New Issue
Block a user