From 0b28c6a254c360be9264b2b8d8a92c254b6e6356 Mon Sep 17 00:00:00 2001
From: Gregor Eichelberger <gregor.eichelberger@tuwien.ac.at>
Date: Fri, 29 Sep 2023 13:06:06 +0200
Subject: [PATCH] MDL-79501 tiny: Fix editing multiple videos

The selection gets lost while opening the modal dialogue to update an
embedded media. Caching the current selection allows us to update the
previously selected node instead of updating the first embedded media.

Signed-off-by: Gregor Eichelberger <gregor.eichelberger@tuwien.ac.at>
---
 lib/editor/tiny/plugins/media/amd/build/embed.min.js  |  2 +-
 .../tiny/plugins/media/amd/build/embed.min.js.map     |  2 +-
 lib/editor/tiny/plugins/media/amd/src/embed.js        | 11 ++++++++---
 3 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/lib/editor/tiny/plugins/media/amd/build/embed.min.js b/lib/editor/tiny/plugins/media/amd/build/embed.min.js
index 55f08de7def..4acf88fb946 100644
--- a/lib/editor/tiny/plugins/media/amd/build/embed.min.js
+++ b/lib/editor/tiny/plugins/media/amd/build/embed.min.js
@@ -1,3 +1,3 @@
-define("tiny_media/embed",["exports","core/templates","core/str","core/modal_factory","core/modal_events","editor_tiny/utils","editor_tiny/options","./common","./embedmodal","./selectors","./options"],(function(_exports,_templates,_str,ModalFactory,ModalEvents,_utils,_options,_common,_embedmodal,_selectors,_options2){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.MediaEmbed=void 0,_templates=_interopRequireDefault(_templates),ModalFactory=_interopRequireWildcard(ModalFactory),ModalEvents=_interopRequireWildcard(ModalEvents),_embedmodal=_interopRequireDefault(_embedmodal),_selectors=_interopRequireDefault(_selectors);_exports.MediaEmbed=class{constructor(editor){_defineProperty(this,"editor",null),_defineProperty(this,"canShowFilePicker",!1),_defineProperty(this,"helpStrings",null),_defineProperty(this,"isUpdating",!1);const permissions=(0,_options2.getEmbedPermissions)(editor);this.canShowFilePicker=permissions.filepicker,this.editor=editor}async getHelpStrings(){if(!this.helpStrings){const[addSource,tracks,subtitles,captions,descriptions,chapters,metadata]=await(0,_str.get_strings)(["addsource_help","tracks_help","subtitles_help","captions_help","descriptions_help","chapters_help","metadata_help"].map((key=>({key:key,component:_common.component}))));this.helpStrings={addSource:addSource,tracks:tracks,subtitles:subtitles,captions:captions,descriptions:descriptions,chapters:chapters,metadata:metadata}}return this.helpStrings}async getTemplateContext(data){const languages=this.prepareMoodleLang(),helpIcons=Array.from(Object.entries(await this.getHelpStrings())).forEach((_ref=>{let[key,text]=_ref;data["".concat(key.toLowerCase(),"helpicon")]={text:text}}));return Object.assign({},{elementid:this.editor.getElement().id,showfilepicker:this.canShowFilePicker,langsinstalled:languages.installed,langsavailable:languages.available,link:!0,video:!1,audio:!1,isupdating:this.isUpdating},data,helpIcons)}async displayDialogue(){const data=Object.assign({},this.getCurrentEmbedData());this.isUpdating=0!==Object.keys(data).length;const modal=await ModalFactory.create({type:_embedmodal.default.TYPE,title:(0,_str.get_string)("createmedia","tiny_media"),templateContext:await this.getTemplateContext(data),removeOnClose:!0,large:!0});this.currentModal=modal,await this.registerEventListeners(modal),modal.show()}getCurrentEmbedData(){const properties=this.getMediumProperties();if(!properties)return{};const processedProperties={};return processedProperties[properties.type.toLowerCase()]=properties,processedProperties.link=!1,processedProperties}getSelectedMedia(){const mediaElm=this.editor.selection.getNode();return mediaElm?"video"===mediaElm.nodeName.toLowerCase()||"audio"===mediaElm.nodeName.toLowerCase()?mediaElm:mediaElm.querySelector("video")?mediaElm.querySelector("video"):mediaElm.querySelector("audio")?mediaElm.querySelector("audio"):null:null}getMediumProperties(){const boolAttr=(elem,attr)=>elem.hasAttribute(attr)&&(elem.getAttribute(attr)||""===elem.getAttribute(attr)),tracks={subtitles:[],captions:[],descriptions:[],chapters:[],metadata:[]},sources=[],medium=this.getSelectedMedia();return medium?(medium.querySelectorAll("track").forEach((track=>{tracks[track.getAttribute("kind")].push({src:track.getAttribute("src"),srclang:track.getAttribute("srclang"),label:track.getAttribute("label"),defaultTrack:boolAttr(track,"default")})})),medium.querySelectorAll("source").forEach((source=>{sources.push(source.src)})),{type:"video"===medium.nodeName.toLowerCase()?_selectors.default.EMBED.mediaTypes.video:_selectors.default.EMBED.mediaTypes.audio,sources:sources,poster:medium.getAttribute("poster"),title:medium.getAttribute("title"),width:medium.getAttribute("width"),height:medium.getAttribute("height"),autoplay:boolAttr(medium,"autoplay"),loop:boolAttr(medium,"loop"),muted:boolAttr(medium,"muted"),controls:boolAttr(medium,"controls"),tracks:tracks}):null}prepareMoodleLang(){const moodleLangs=(0,_options.getMoodleLang)(this.editor),currentLanguage=(0,_options.getCurrentLanguage)(this.editor);return{installed:Object.entries(moodleLangs.installed).map((_ref2=>{let[lang,code]=_ref2;return{lang:lang,code:code,default:lang===currentLanguage}})),available:Object.entries(moodleLangs.available).map((_ref3=>{let[lang,code]=_ref3;return{lang:lang,code:code,default:lang===currentLanguage}}))}}getMoodleLangObj(subtitleLang){const{available:available}=(0,_options.getMoodleLang)(this.editor);return available[subtitleLang]?{lang:subtitleLang,code:available[subtitleLang]}:null}filePickerCallback(params,element,fpType){if(""!==params.url){const tabPane=element.closest(".tab-pane");if(element.closest(_selectors.default.EMBED.elements.source).querySelector(_selectors.default.EMBED.elements.url).value=params.url,tabPane.id===this.editor.getElement().id+"_"+_selectors.default.EMBED.mediaTypes.link.toLowerCase()&&(tabPane.querySelector(_selectors.default.EMBED.elements.name).value=params.file),"subtitle"===fpType){const subtitleLang=params.file.split(".vtt")[0].split("-").slice(-1)[0],langObj=this.getMoodleLangObj(subtitleLang);if(langObj){const track=element.closest(_selectors.default.EMBED.elements.track);track.querySelector(_selectors.default.EMBED.elements.trackLabel).value=langObj.lang.trim(),track.querySelector(_selectors.default.EMBED.elements.trackLang).value=langObj.code}}}}addMediaSourceComponent(element,callback){const sourceElement=element.closest(_selectors.default.EMBED.elements.source+_selectors.default.EMBED.elements.mediaSource),clone=sourceElement.cloneNode(!0);sourceElement.querySelector(".removecomponent-wrapper").classList.remove("hidden"),sourceElement.querySelector(".addcomponent-wrapper").classList.add("hidden"),sourceElement.parentNode.insertBefore(clone,sourceElement.nextSibling),callback&&callback(clone)}removeMediaSourceComponent(element){element.closest(_selectors.default.EMBED.elements.source+_selectors.default.EMBED.elements.mediaSource).remove()}addTrackComponent(element,callback){const trackElement=element.closest(_selectors.default.EMBED.elements.track),clone=trackElement.cloneNode(!0);trackElement.querySelector(".removecomponent-wrapper").classList.remove("hidden"),trackElement.querySelector(".addcomponent-wrapper").classList.add("hidden"),trackElement.parentNode.insertBefore(clone,trackElement.nextSibling),callback&&callback(clone)}removeTrackComponent(element){element.closest(_selectors.default.EMBED.elements.track).remove()}getMediumTypeFromTabPane(tabPane){return tabPane.getAttribute("data-medium-type")}getTrackTypeFromTabPane(tabPane){return tabPane.getAttribute("data-track-kind")}getMediaHTML(form){const mediumType=this.getMediumTypeFromTabPane(form.querySelector(".root.tab-content > .tab-pane.active")),tabContent=form.querySelector(_selectors.default.EMBED.elements[mediumType.toLowerCase()+"Pane"]);return this["getMediaHTML"+mediumType[0].toUpperCase()+mediumType.substr(1)](tabContent)}getMediaHTMLLink(tab){const context={url:tab.querySelector(_selectors.default.EMBED.elements.url).value,name:tab.querySelector(_selectors.default.EMBED.elements.name).value||!1};return context.url?_templates.default.renderForPromise("tiny_media/embed_media_link",context):""}getMediaHTMLVideo(tab){const context=this.getContextForMediaHTML(tab);return context.width=tab.querySelector(_selectors.default.EMBED.elements.width).value||!1,context.height=tab.querySelector(_selectors.default.EMBED.elements.height).value||!1,context.poster=tab.querySelector("".concat(_selectors.default.EMBED.elements.posterSource," ").concat(_selectors.default.EMBED.elements.url)).value||!1,context.sources.length?_templates.default.renderForPromise("tiny_media/embed_media_video",context):""}getMediaHTMLAudio(tab){const context=this.getContextForMediaHTML(tab);return context.sources.length?_templates.default.renderForPromise("tiny_media/embed_media_audio",context):""}getContextForMediaHTML(tab){const tracks=Array.from(tab.querySelectorAll(_selectors.default.EMBED.elements.track)).map((track=>({track:track.querySelector(_selectors.default.EMBED.elements.trackSource+" "+_selectors.default.EMBED.elements.url).value,kind:this.getTrackTypeFromTabPane(track.closest(".tab-pane")),label:track.querySelector(_selectors.default.EMBED.elements.trackLabel).value||track.querySelector(_selectors.default.EMBED.elements.trackLang).value,srclang:track.querySelector(_selectors.default.EMBED.elements.trackLang).value,defaultTrack:track.querySelector(_selectors.default.EMBED.elements.trackDefault).checked?"true":null}))).filter((track=>!!track.track));return{sources:Array.from(tab.querySelectorAll(_selectors.default.EMBED.elements.mediaSource+" "+_selectors.default.EMBED.elements.url)).filter((source=>!!source.value)).map((source=>source.value)),description:tab.querySelector(_selectors.default.EMBED.elements.mediaSource+" "+_selectors.default.EMBED.elements.url).value||!1,tracks:tracks,showControls:tab.querySelector(_selectors.default.EMBED.elements.mediaControl).checked,autoplay:tab.querySelector(_selectors.default.EMBED.elements.mediaAutoplay).checked,muted:tab.querySelector(_selectors.default.EMBED.elements.mediaMute).checked,loop:tab.querySelector(_selectors.default.EMBED.elements.mediaLoop).checked,title:tab.querySelector(_selectors.default.EMBED.elements.title).value||!1}}getFilepickerTypeFromElement(element){return element.closest(_selectors.default.EMBED.elements.posterSource)?"image":element.closest(_selectors.default.EMBED.elements.trackSource)?"subtitle":"media"}async clickHandler(e){const element=e.target;if(element.closest(_selectors.default.EMBED.actions.mediaBrowser)){e.preventDefault();const fpType=this.getFilepickerTypeFromElement(element),params=await(0,_utils.displayFilepicker)(this.editor,fpType);this.filePickerCallback(params,element,fpType)}element.closest(_selectors.default.EMBED.elements.mediaSource+" .addcomponent")&&(e.preventDefault(),this.addMediaSourceComponent(element));element.closest(_selectors.default.EMBED.elements.mediaSource+" .removecomponent")&&(e.preventDefault(),this.removeMediaSourceComponent(element));element.closest(_selectors.default.EMBED.elements.track+" .addcomponent")&&(e.preventDefault(),this.addTrackComponent(element));element.closest(_selectors.default.EMBED.elements.track+" .removecomponent")&&(e.preventDefault(),this.removeTrackComponent(element));const trackDefaultAction=element.closest(_selectors.default.EMBED.elements.trackDefault);if(trackDefaultAction&&trackDefaultAction.checked){const getKind=el=>this.getTrackTypeFromTabPane(el.parentElement.closest(".tab-pane"));element.parentElement.closest(".root.tab-content").querySelectorAll(_selectors.default.EMBED.elements.trackDefault).forEach((select=>{select!==element&&getKind(element)===getKind(select)&&(select.checked=!1)}))}}async handleDialogueSubmission(event,modal){const{html:html}=await this.getMediaHTML(modal.getRoot()[0]);if(html)if(this.isUpdating){this.getSelectedMedia().outerHTML=html,this.isUpdating=!1}else this.editor.insertContent(html)}async registerEventListeners(modal){await modal.getBody();const $root=modal.getRoot(),root=$root[0];this.canShowFilePicker&&root.addEventListener("click",this.clickHandler.bind(this)),$root.on(ModalEvents.save,this.handleDialogueSubmission.bind(this)),$root.on(ModalEvents.hidden,(()=>{this.currentModal.destroy()})),$root.on(ModalEvents.shown,(()=>{root.querySelectorAll(_selectors.default.EMBED.elements.trackLang).forEach((dropdown=>{const defaultVal=dropdown.getAttribute("data-value");defaultVal&&(dropdown.value=defaultVal)}))}))}}}));
+define("tiny_media/embed",["exports","core/templates","core/str","core/modal_factory","core/modal_events","editor_tiny/utils","editor_tiny/options","./common","./embedmodal","./selectors","./options"],(function(_exports,_templates,_str,ModalFactory,ModalEvents,_utils,_options,_common,_embedmodal,_selectors,_options2){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.MediaEmbed=void 0,_templates=_interopRequireDefault(_templates),ModalFactory=_interopRequireWildcard(ModalFactory),ModalEvents=_interopRequireWildcard(ModalEvents),_embedmodal=_interopRequireDefault(_embedmodal),_selectors=_interopRequireDefault(_selectors);_exports.MediaEmbed=class{constructor(editor){_defineProperty(this,"editor",null),_defineProperty(this,"canShowFilePicker",!1),_defineProperty(this,"helpStrings",null),_defineProperty(this,"isUpdating",!1),_defineProperty(this,"selectedMedia",null);const permissions=(0,_options2.getEmbedPermissions)(editor);this.canShowFilePicker=permissions.filepicker,this.editor=editor}async getHelpStrings(){if(!this.helpStrings){const[addSource,tracks,subtitles,captions,descriptions,chapters,metadata]=await(0,_str.get_strings)(["addsource_help","tracks_help","subtitles_help","captions_help","descriptions_help","chapters_help","metadata_help"].map((key=>({key:key,component:_common.component}))));this.helpStrings={addSource:addSource,tracks:tracks,subtitles:subtitles,captions:captions,descriptions:descriptions,chapters:chapters,metadata:metadata}}return this.helpStrings}async getTemplateContext(data){const languages=this.prepareMoodleLang(),helpIcons=Array.from(Object.entries(await this.getHelpStrings())).forEach((_ref=>{let[key,text]=_ref;data["".concat(key.toLowerCase(),"helpicon")]={text:text}}));return Object.assign({},{elementid:this.editor.getElement().id,showfilepicker:this.canShowFilePicker,langsinstalled:languages.installed,langsavailable:languages.available,link:!0,video:!1,audio:!1,isupdating:this.isUpdating},data,helpIcons)}async displayDialogue(){this.selectedMedia=this.getSelectedMedia();const data=Object.assign({},this.getCurrentEmbedData());this.isUpdating=0!==Object.keys(data).length;const modal=await ModalFactory.create({type:_embedmodal.default.TYPE,title:(0,_str.get_string)("createmedia","tiny_media"),templateContext:await this.getTemplateContext(data),removeOnClose:!0,large:!0});this.currentModal=modal,await this.registerEventListeners(modal),modal.show()}getCurrentEmbedData(){const properties=this.getMediumProperties();if(!properties)return{};const processedProperties={};return processedProperties[properties.type.toLowerCase()]=properties,processedProperties.link=!1,processedProperties}getSelectedMedia(){const mediaElm=this.editor.selection.getNode();return mediaElm?"video"===mediaElm.nodeName.toLowerCase()||"audio"===mediaElm.nodeName.toLowerCase()?mediaElm:mediaElm.querySelector("video")?mediaElm.querySelector("video"):mediaElm.querySelector("audio")?mediaElm.querySelector("audio"):null:null}getMediumProperties(){const boolAttr=(elem,attr)=>elem.hasAttribute(attr)&&(elem.getAttribute(attr)||""===elem.getAttribute(attr)),tracks={subtitles:[],captions:[],descriptions:[],chapters:[],metadata:[]},sources=[],medium=this.selectedMedia;return medium?(medium.querySelectorAll("track").forEach((track=>{tracks[track.getAttribute("kind")].push({src:track.getAttribute("src"),srclang:track.getAttribute("srclang"),label:track.getAttribute("label"),defaultTrack:boolAttr(track,"default")})})),medium.querySelectorAll("source").forEach((source=>{sources.push(source.src)})),{type:"video"===medium.nodeName.toLowerCase()?_selectors.default.EMBED.mediaTypes.video:_selectors.default.EMBED.mediaTypes.audio,sources:sources,poster:medium.getAttribute("poster"),title:medium.getAttribute("title"),width:medium.getAttribute("width"),height:medium.getAttribute("height"),autoplay:boolAttr(medium,"autoplay"),loop:boolAttr(medium,"loop"),muted:boolAttr(medium,"muted"),controls:boolAttr(medium,"controls"),tracks:tracks}):null}prepareMoodleLang(){const moodleLangs=(0,_options.getMoodleLang)(this.editor),currentLanguage=(0,_options.getCurrentLanguage)(this.editor);return{installed:Object.entries(moodleLangs.installed).map((_ref2=>{let[lang,code]=_ref2;return{lang:lang,code:code,default:lang===currentLanguage}})),available:Object.entries(moodleLangs.available).map((_ref3=>{let[lang,code]=_ref3;return{lang:lang,code:code,default:lang===currentLanguage}}))}}getMoodleLangObj(subtitleLang){const{available:available}=(0,_options.getMoodleLang)(this.editor);return available[subtitleLang]?{lang:subtitleLang,code:available[subtitleLang]}:null}filePickerCallback(params,element,fpType){if(""!==params.url){const tabPane=element.closest(".tab-pane");if(element.closest(_selectors.default.EMBED.elements.source).querySelector(_selectors.default.EMBED.elements.url).value=params.url,tabPane.id===this.editor.getElement().id+"_"+_selectors.default.EMBED.mediaTypes.link.toLowerCase()&&(tabPane.querySelector(_selectors.default.EMBED.elements.name).value=params.file),"subtitle"===fpType){const subtitleLang=params.file.split(".vtt")[0].split("-").slice(-1)[0],langObj=this.getMoodleLangObj(subtitleLang);if(langObj){const track=element.closest(_selectors.default.EMBED.elements.track);track.querySelector(_selectors.default.EMBED.elements.trackLabel).value=langObj.lang.trim(),track.querySelector(_selectors.default.EMBED.elements.trackLang).value=langObj.code}}}}addMediaSourceComponent(element,callback){const sourceElement=element.closest(_selectors.default.EMBED.elements.source+_selectors.default.EMBED.elements.mediaSource),clone=sourceElement.cloneNode(!0);sourceElement.querySelector(".removecomponent-wrapper").classList.remove("hidden"),sourceElement.querySelector(".addcomponent-wrapper").classList.add("hidden"),sourceElement.parentNode.insertBefore(clone,sourceElement.nextSibling),callback&&callback(clone)}removeMediaSourceComponent(element){element.closest(_selectors.default.EMBED.elements.source+_selectors.default.EMBED.elements.mediaSource).remove()}addTrackComponent(element,callback){const trackElement=element.closest(_selectors.default.EMBED.elements.track),clone=trackElement.cloneNode(!0);trackElement.querySelector(".removecomponent-wrapper").classList.remove("hidden"),trackElement.querySelector(".addcomponent-wrapper").classList.add("hidden"),trackElement.parentNode.insertBefore(clone,trackElement.nextSibling),callback&&callback(clone)}removeTrackComponent(element){element.closest(_selectors.default.EMBED.elements.track).remove()}getMediumTypeFromTabPane(tabPane){return tabPane.getAttribute("data-medium-type")}getTrackTypeFromTabPane(tabPane){return tabPane.getAttribute("data-track-kind")}getMediaHTML(form){const mediumType=this.getMediumTypeFromTabPane(form.querySelector(".root.tab-content > .tab-pane.active")),tabContent=form.querySelector(_selectors.default.EMBED.elements[mediumType.toLowerCase()+"Pane"]);return this["getMediaHTML"+mediumType[0].toUpperCase()+mediumType.substr(1)](tabContent)}getMediaHTMLLink(tab){const context={url:tab.querySelector(_selectors.default.EMBED.elements.url).value,name:tab.querySelector(_selectors.default.EMBED.elements.name).value||!1};return context.url?_templates.default.renderForPromise("tiny_media/embed_media_link",context):""}getMediaHTMLVideo(tab){const context=this.getContextForMediaHTML(tab);return context.width=tab.querySelector(_selectors.default.EMBED.elements.width).value||!1,context.height=tab.querySelector(_selectors.default.EMBED.elements.height).value||!1,context.poster=tab.querySelector("".concat(_selectors.default.EMBED.elements.posterSource," ").concat(_selectors.default.EMBED.elements.url)).value||!1,context.sources.length?_templates.default.renderForPromise("tiny_media/embed_media_video",context):""}getMediaHTMLAudio(tab){const context=this.getContextForMediaHTML(tab);return context.sources.length?_templates.default.renderForPromise("tiny_media/embed_media_audio",context):""}getContextForMediaHTML(tab){const tracks=Array.from(tab.querySelectorAll(_selectors.default.EMBED.elements.track)).map((track=>({track:track.querySelector(_selectors.default.EMBED.elements.trackSource+" "+_selectors.default.EMBED.elements.url).value,kind:this.getTrackTypeFromTabPane(track.closest(".tab-pane")),label:track.querySelector(_selectors.default.EMBED.elements.trackLabel).value||track.querySelector(_selectors.default.EMBED.elements.trackLang).value,srclang:track.querySelector(_selectors.default.EMBED.elements.trackLang).value,defaultTrack:track.querySelector(_selectors.default.EMBED.elements.trackDefault).checked?"true":null}))).filter((track=>!!track.track));return{sources:Array.from(tab.querySelectorAll(_selectors.default.EMBED.elements.mediaSource+" "+_selectors.default.EMBED.elements.url)).filter((source=>!!source.value)).map((source=>source.value)),description:tab.querySelector(_selectors.default.EMBED.elements.mediaSource+" "+_selectors.default.EMBED.elements.url).value||!1,tracks:tracks,showControls:tab.querySelector(_selectors.default.EMBED.elements.mediaControl).checked,autoplay:tab.querySelector(_selectors.default.EMBED.elements.mediaAutoplay).checked,muted:tab.querySelector(_selectors.default.EMBED.elements.mediaMute).checked,loop:tab.querySelector(_selectors.default.EMBED.elements.mediaLoop).checked,title:tab.querySelector(_selectors.default.EMBED.elements.title).value||!1}}getFilepickerTypeFromElement(element){return element.closest(_selectors.default.EMBED.elements.posterSource)?"image":element.closest(_selectors.default.EMBED.elements.trackSource)?"subtitle":"media"}async clickHandler(e){const element=e.target;if(element.closest(_selectors.default.EMBED.actions.mediaBrowser)){e.preventDefault();const fpType=this.getFilepickerTypeFromElement(element),params=await(0,_utils.displayFilepicker)(this.editor,fpType);this.filePickerCallback(params,element,fpType)}element.closest(_selectors.default.EMBED.elements.mediaSource+" .addcomponent")&&(e.preventDefault(),this.addMediaSourceComponent(element));element.closest(_selectors.default.EMBED.elements.mediaSource+" .removecomponent")&&(e.preventDefault(),this.removeMediaSourceComponent(element));element.closest(_selectors.default.EMBED.elements.track+" .addcomponent")&&(e.preventDefault(),this.addTrackComponent(element));element.closest(_selectors.default.EMBED.elements.track+" .removecomponent")&&(e.preventDefault(),this.removeTrackComponent(element));const trackDefaultAction=element.closest(_selectors.default.EMBED.elements.trackDefault);if(trackDefaultAction&&trackDefaultAction.checked){const getKind=el=>this.getTrackTypeFromTabPane(el.parentElement.closest(".tab-pane"));element.parentElement.closest(".root.tab-content").querySelectorAll(_selectors.default.EMBED.elements.trackDefault).forEach((select=>{select!==element&&getKind(element)===getKind(select)&&(select.checked=!1)}))}}async handleDialogueSubmission(event,modal){const{html:html}=await this.getMediaHTML(modal.getRoot()[0]);html&&(this.isUpdating?(this.selectedMedia.outerHTML=html,this.isUpdating=!1):this.editor.insertContent(html))}async registerEventListeners(modal){await modal.getBody();const $root=modal.getRoot(),root=$root[0];this.canShowFilePicker&&root.addEventListener("click",this.clickHandler.bind(this)),$root.on(ModalEvents.save,this.handleDialogueSubmission.bind(this)),$root.on(ModalEvents.hidden,(()=>{this.currentModal.destroy()})),$root.on(ModalEvents.shown,(()=>{root.querySelectorAll(_selectors.default.EMBED.elements.trackLang).forEach((dropdown=>{const defaultVal=dropdown.getAttribute("data-value");defaultVal&&(dropdown.value=defaultVal)}))}))}}}));
 
 //# sourceMappingURL=embed.min.js.map
\ No newline at end of file
diff --git a/lib/editor/tiny/plugins/media/amd/build/embed.min.js.map b/lib/editor/tiny/plugins/media/amd/build/embed.min.js.map
index 00f2f47086f..d85d27f14ad 100644
--- a/lib/editor/tiny/plugins/media/amd/build/embed.min.js.map
+++ b/lib/editor/tiny/plugins/media/amd/build/embed.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"embed.min.js","sources":["../src/embed.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Tiny Media plugin Embed class for Moodle.\n *\n * @module      tiny_media/embed\n * @copyright   2022 Huong Nguyen <huongnv13@gmail.com>\n * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Templates from 'core/templates';\nimport {\n    get_string as getString,\n    get_strings as getStrings,\n} from 'core/str';\nimport * as ModalFactory from 'core/modal_factory';\nimport * as ModalEvents from 'core/modal_events';\nimport {displayFilepicker} from 'editor_tiny/utils';\nimport {getCurrentLanguage, getMoodleLang} from 'editor_tiny/options';\nimport {component} from \"./common\";\nimport Modal from './embedmodal';\nimport Selectors from './selectors';\nimport {getEmbedPermissions} from './options';\n\nexport const MediaEmbed = class {\n    editor = null;\n    canShowFilePicker = false;\n\n    /**\n     * @property {Object} The names of the alignment options.\n     */\n    helpStrings = null;\n\n    /**\n     * @property {boolean} Indicate that the user is updating the media or not.\n     */\n    isUpdating = false;\n\n    constructor(editor) {\n        const permissions = getEmbedPermissions(editor);\n        this.canShowFilePicker = permissions.filepicker;\n        this.editor = editor;\n    }\n\n    async getHelpStrings() {\n        if (!this.helpStrings) {\n            const [addSource, tracks, subtitles, captions, descriptions, chapters, metadata] = await getStrings([\n                'addsource_help',\n                'tracks_help',\n                'subtitles_help',\n                'captions_help',\n                'descriptions_help',\n                'chapters_help',\n                'metadata_help',\n            ].map((key) => ({\n                key,\n                component,\n            })));\n\n            this.helpStrings = {addSource, tracks, subtitles, captions, descriptions, chapters, metadata};\n        }\n\n        return this.helpStrings;\n    }\n\n    async getTemplateContext(data) {\n        const languages = this.prepareMoodleLang();\n\n        const helpIcons = Array.from(Object.entries(await this.getHelpStrings())).forEach(([key, text]) => {\n            data[`${key.toLowerCase()}helpicon`] = {text};\n        });\n\n        return Object.assign({}, {\n            elementid: this.editor.getElement().id,\n            showfilepicker: this.canShowFilePicker,\n            langsinstalled: languages.installed,\n            langsavailable: languages.available,\n            link: true,\n            video: false,\n            audio: false,\n            isupdating: this.isUpdating,\n        }, data, helpIcons);\n    }\n\n    async displayDialogue() {\n        const data = Object.assign({}, this.getCurrentEmbedData());\n        this.isUpdating = Object.keys(data).length !== 0;\n\n        const modal = await ModalFactory.create({\n            type: Modal.TYPE,\n            title: getString('createmedia', 'tiny_media'),\n            templateContext: await this.getTemplateContext(data),\n            removeOnClose: true,\n            large: true,\n        });\n\n        this.currentModal = modal;\n        await this.registerEventListeners(modal);\n        modal.show();\n    }\n\n    getCurrentEmbedData() {\n        const properties = this.getMediumProperties();\n        if (!properties) {\n            return {};\n        }\n\n        const processedProperties = {};\n        processedProperties[properties.type.toLowerCase()] = properties;\n        processedProperties.link = false;\n\n        return processedProperties;\n    }\n\n    getSelectedMedia() {\n        const mediaElm = this.editor.selection.getNode();\n\n        if (!mediaElm) {\n            return null;\n        }\n\n        if (mediaElm.nodeName.toLowerCase() === 'video' || mediaElm.nodeName.toLowerCase() === 'audio') {\n            return mediaElm;\n        }\n\n        if (mediaElm.querySelector('video')) {\n            return mediaElm.querySelector('video');\n        }\n\n        if (mediaElm.querySelector('audio')) {\n            return mediaElm.querySelector('audio');\n        }\n\n        return null;\n    }\n\n    getMediumProperties() {\n        const boolAttr = (elem, attr) => {\n            // As explained in MDL-64175, some OS (like Ubuntu), are removing the value for these attributes.\n            // So in order to check if attr=\"true\", we need to check if the attribute exists and if the value is empty or true.\n            return (elem.hasAttribute(attr) && (elem.getAttribute(attr) || elem.getAttribute(attr) === ''));\n        };\n\n        const tracks = {\n            subtitles: [],\n            captions: [],\n            descriptions: [],\n            chapters: [],\n            metadata: []\n        };\n        const sources = [];\n\n        const medium = this.getSelectedMedia();\n        if (!medium) {\n            return null;\n        }\n        medium.querySelectorAll('track').forEach((track) => {\n            tracks[track.getAttribute('kind')].push({\n                src: track.getAttribute('src'),\n                srclang: track.getAttribute('srclang'),\n                label: track.getAttribute('label'),\n                defaultTrack: boolAttr(track, 'default')\n            });\n        });\n\n        medium.querySelectorAll('source').forEach((source) => {\n            sources.push(source.src);\n        });\n\n        return {\n            type: medium.nodeName.toLowerCase() === 'video' ? Selectors.EMBED.mediaTypes.video : Selectors.EMBED.mediaTypes.audio,\n            sources,\n            poster: medium.getAttribute('poster'),\n            title: medium.getAttribute('title'),\n            width: medium.getAttribute('width'),\n            height: medium.getAttribute('height'),\n            autoplay: boolAttr(medium, 'autoplay'),\n            loop: boolAttr(medium, 'loop'),\n            muted: boolAttr(medium, 'muted'),\n            controls: boolAttr(medium, 'controls'),\n            tracks,\n        };\n    }\n\n    prepareMoodleLang() {\n        const moodleLangs = getMoodleLang(this.editor);\n        const currentLanguage = getCurrentLanguage(this.editor);\n\n        const installed = Object.entries(moodleLangs.installed).map(([lang, code]) => ({\n            lang,\n            code,\n            \"default\": lang === currentLanguage,\n        }));\n\n        const available = Object.entries(moodleLangs.available).map(([lang, code]) => ({\n            lang,\n            code,\n            \"default\": lang === currentLanguage,\n        }));\n\n        return {\n            installed,\n            available,\n        };\n    }\n\n    getMoodleLangObj(subtitleLang) {\n        const {available} = getMoodleLang(this.editor);\n\n        if (available[subtitleLang]) {\n            return {\n                lang: subtitleLang,\n                code: available[subtitleLang],\n            };\n        }\n\n        return null;\n    }\n\n    filePickerCallback(params, element, fpType) {\n        if (params.url !== '') {\n            const tabPane = element.closest('.tab-pane');\n            element.closest(Selectors.EMBED.elements.source).querySelector(Selectors.EMBED.elements.url).value = params.url;\n\n            if (tabPane.id === this.editor.getElement().id + '_' + Selectors.EMBED.mediaTypes.link.toLowerCase()) {\n                tabPane.querySelector(Selectors.EMBED.elements.name).value = params.file;\n            }\n\n            if (fpType === 'subtitle') {\n                // If the file is subtitle file. We need to match the language and label for that file.\n                const subtitleLang = params.file.split('.vtt')[0].split('-').slice(-1)[0];\n                const langObj = this.getMoodleLangObj(subtitleLang);\n                if (langObj) {\n                    const track = element.closest(Selectors.EMBED.elements.track);\n                    track.querySelector(Selectors.EMBED.elements.trackLabel).value = langObj.lang.trim();\n                    track.querySelector(Selectors.EMBED.elements.trackLang).value = langObj.code;\n                }\n            }\n        }\n    }\n\n    addMediaSourceComponent(element, callback) {\n        const sourceElement = element.closest(Selectors.EMBED.elements.source + Selectors.EMBED.elements.mediaSource);\n        const clone = sourceElement.cloneNode(true);\n\n        sourceElement.querySelector('.removecomponent-wrapper').classList.remove('hidden');\n        sourceElement.querySelector('.addcomponent-wrapper').classList.add('hidden');\n\n        sourceElement.parentNode.insertBefore(clone, sourceElement.nextSibling);\n\n        if (callback) {\n            callback(clone);\n        }\n    }\n\n    removeMediaSourceComponent(element) {\n        const sourceElement = element.closest(Selectors.EMBED.elements.source + Selectors.EMBED.elements.mediaSource);\n        sourceElement.remove();\n    }\n\n    addTrackComponent(element, callback) {\n        const trackElement = element.closest(Selectors.EMBED.elements.track);\n        const clone = trackElement.cloneNode(true);\n\n        trackElement.querySelector('.removecomponent-wrapper').classList.remove('hidden');\n        trackElement.querySelector('.addcomponent-wrapper').classList.add('hidden');\n\n        trackElement.parentNode.insertBefore(clone, trackElement.nextSibling);\n\n        if (callback) {\n            callback(clone);\n        }\n    }\n\n    removeTrackComponent(element) {\n        const sourceElement = element.closest(Selectors.EMBED.elements.track);\n        sourceElement.remove();\n    }\n\n    getMediumTypeFromTabPane(tabPane) {\n        return tabPane.getAttribute('data-medium-type');\n    }\n\n    getTrackTypeFromTabPane(tabPane) {\n        return tabPane.getAttribute('data-track-kind');\n    }\n\n    getMediaHTML(form) {\n        const mediumType = this.getMediumTypeFromTabPane(form.querySelector('.root.tab-content > .tab-pane.active'));\n        const tabContent = form.querySelector(Selectors.EMBED.elements[mediumType.toLowerCase() + 'Pane']);\n\n        return this['getMediaHTML' + mediumType[0].toUpperCase() + mediumType.substr(1)](tabContent);\n    }\n\n    getMediaHTMLLink(tab) {\n        const context = {\n            url: tab.querySelector(Selectors.EMBED.elements.url).value,\n            name: tab.querySelector(Selectors.EMBED.elements.name).value || false\n        };\n\n        return context.url ? Templates.renderForPromise('tiny_media/embed_media_link', context) : '';\n    }\n\n    getMediaHTMLVideo(tab) {\n        const context = this.getContextForMediaHTML(tab);\n        context.width = tab.querySelector(Selectors.EMBED.elements.width).value || false;\n        context.height = tab.querySelector(Selectors.EMBED.elements.height).value || false;\n        context.poster = tab.querySelector(\n            `${Selectors.EMBED.elements.posterSource} ${Selectors.EMBED.elements.url}`\n        ).value || false;\n\n        return context.sources.length ? Templates.renderForPromise('tiny_media/embed_media_video', context) : '';\n    }\n\n    getMediaHTMLAudio(tab) {\n        const context = this.getContextForMediaHTML(tab);\n\n        return context.sources.length ? Templates.renderForPromise('tiny_media/embed_media_audio', context) : '';\n    }\n\n    getContextForMediaHTML(tab) {\n        const tracks = Array.from(tab.querySelectorAll(Selectors.EMBED.elements.track)).map(track => ({\n            track: track.querySelector(Selectors.EMBED.elements.trackSource + ' ' + Selectors.EMBED.elements.url).value,\n            kind: this.getTrackTypeFromTabPane(track.closest('.tab-pane')),\n            label: track.querySelector(Selectors.EMBED.elements.trackLabel).value ||\n                track.querySelector(Selectors.EMBED.elements.trackLang).value,\n            srclang: track.querySelector(Selectors.EMBED.elements.trackLang).value,\n            defaultTrack: track.querySelector(Selectors.EMBED.elements.trackDefault).checked ? \"true\" : null\n        })).filter((track) => !!track.track);\n\n        const sources = Array.from(tab.querySelectorAll(Selectors.EMBED.elements.mediaSource + ' '\n            + Selectors.EMBED.elements.url))\n                .filter((source) => !!source.value)\n                .map((source) => source.value);\n\n        return {\n            sources,\n            description: tab.querySelector(Selectors.EMBED.elements.mediaSource + ' '\n                + Selectors.EMBED.elements.url).value || false,\n            tracks,\n            showControls: tab.querySelector(Selectors.EMBED.elements.mediaControl).checked,\n            autoplay: tab.querySelector(Selectors.EMBED.elements.mediaAutoplay).checked,\n            muted: tab.querySelector(Selectors.EMBED.elements.mediaMute).checked,\n            loop: tab.querySelector(Selectors.EMBED.elements.mediaLoop).checked,\n            title: tab.querySelector(Selectors.EMBED.elements.title).value || false\n        };\n    }\n\n    getFilepickerTypeFromElement(element) {\n        if (element.closest(Selectors.EMBED.elements.posterSource)) {\n            return 'image';\n        }\n        if (element.closest(Selectors.EMBED.elements.trackSource)) {\n            return 'subtitle';\n        }\n\n        return 'media';\n    }\n\n    async clickHandler(e) {\n        const element = e.target;\n\n        const mediaBrowser = element.closest(Selectors.EMBED.actions.mediaBrowser);\n        if (mediaBrowser) {\n            e.preventDefault();\n            const fpType = this.getFilepickerTypeFromElement(element);\n            const params = await displayFilepicker(this.editor, fpType);\n            this.filePickerCallback(params, element, fpType);\n        }\n\n        const addComponentSourceAction = element.closest(Selectors.EMBED.elements.mediaSource + ' .addcomponent');\n        if (addComponentSourceAction) {\n            e.preventDefault();\n            this.addMediaSourceComponent(element);\n        }\n\n        const removeComponentSourceAction = element.closest(Selectors.EMBED.elements.mediaSource + ' .removecomponent');\n        if (removeComponentSourceAction) {\n            e.preventDefault();\n            this.removeMediaSourceComponent(element);\n        }\n\n        const addComponentTrackAction = element.closest(Selectors.EMBED.elements.track + ' .addcomponent');\n        if (addComponentTrackAction) {\n            e.preventDefault();\n            this.addTrackComponent(element);\n        }\n\n        const removeComponentTrackAction = element.closest(Selectors.EMBED.elements.track + ' .removecomponent');\n        if (removeComponentTrackAction) {\n            e.preventDefault();\n            this.removeTrackComponent(element);\n        }\n\n        // Only allow one track per tab to be selected as \"default\".\n        const trackDefaultAction = element.closest(Selectors.EMBED.elements.trackDefault);\n        if (trackDefaultAction && trackDefaultAction.checked) {\n            const getKind = (el) => this.getTrackTypeFromTabPane(el.parentElement.closest('.tab-pane'));\n\n            element.parentElement\n                .closest('.root.tab-content')\n                .querySelectorAll(Selectors.EMBED.elements.trackDefault)\n                .forEach((select) => {\n                    if (select !== element && getKind(element) === getKind(select)) {\n                        select.checked = false;\n                    }\n                });\n        }\n    }\n\n    async handleDialogueSubmission(event, modal) {\n        const {html} = await this.getMediaHTML(modal.getRoot()[0]);\n        if (html) {\n            if (this.isUpdating) {\n                const selectedNode = this.getSelectedMedia();\n                selectedNode.outerHTML = html;\n                this.isUpdating = false;\n            } else {\n                this.editor.insertContent(html);\n            }\n        }\n    }\n\n    async registerEventListeners(modal) {\n        await modal.getBody();\n        const $root = modal.getRoot();\n        const root = $root[0];\n        if (this.canShowFilePicker) {\n            root.addEventListener('click', this.clickHandler.bind(this));\n        }\n\n        $root.on(ModalEvents.save, this.handleDialogueSubmission.bind(this));\n        $root.on(ModalEvents.hidden, () => {\n            this.currentModal.destroy();\n        });\n        $root.on(ModalEvents.shown, () => {\n            root.querySelectorAll(Selectors.EMBED.elements.trackLang).forEach((dropdown) => {\n                const defaultVal = dropdown.getAttribute('data-value');\n                if (defaultVal) {\n                    dropdown.value = defaultVal;\n                }\n            });\n        });\n    }\n};\n"],"names":["constructor","editor","permissions","canShowFilePicker","filepicker","this","helpStrings","addSource","tracks","subtitles","captions","descriptions","chapters","metadata","map","key","component","data","languages","prepareMoodleLang","helpIcons","Array","from","Object","entries","getHelpStrings","forEach","_ref","text","toLowerCase","assign","elementid","getElement","id","showfilepicker","langsinstalled","installed","langsavailable","available","link","video","audio","isupdating","isUpdating","getCurrentEmbedData","keys","length","modal","ModalFactory","create","type","Modal","TYPE","title","templateContext","getTemplateContext","removeOnClose","large","currentModal","registerEventListeners","show","properties","getMediumProperties","processedProperties","getSelectedMedia","mediaElm","selection","getNode","nodeName","querySelector","boolAttr","elem","attr","hasAttribute","getAttribute","sources","medium","querySelectorAll","track","push","src","srclang","label","defaultTrack","source","Selectors","EMBED","mediaTypes","poster","width","height","autoplay","loop","muted","controls","moodleLangs","currentLanguage","_ref2","lang","code","_ref3","getMoodleLangObj","subtitleLang","filePickerCallback","params","element","fpType","url","tabPane","closest","elements","value","name","file","split","slice","langObj","trackLabel","trim","trackLang","addMediaSourceComponent","callback","sourceElement","mediaSource","clone","cloneNode","classList","remove","add","parentNode","insertBefore","nextSibling","removeMediaSourceComponent","addTrackComponent","trackElement","removeTrackComponent","getMediumTypeFromTabPane","getTrackTypeFromTabPane","getMediaHTML","form","mediumType","tabContent","toUpperCase","substr","getMediaHTMLLink","tab","context","Templates","renderForPromise","getMediaHTMLVideo","getContextForMediaHTML","posterSource","getMediaHTMLAudio","trackSource","kind","trackDefault","checked","filter","description","showControls","mediaControl","mediaAutoplay","mediaMute","mediaLoop","getFilepickerTypeFromElement","e","target","actions","mediaBrowser","preventDefault","trackDefaultAction","getKind","el","parentElement","select","event","html","getRoot","outerHTML","insertContent","getBody","$root","root","addEventListener","clickHandler","bind","on","ModalEvents","save","handleDialogueSubmission","hidden","destroy","shown","dropdown","defaultVal"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"embed.min.js","sources":["../src/embed.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Tiny Media plugin Embed class for Moodle.\n *\n * @module      tiny_media/embed\n * @copyright   2022 Huong Nguyen <huongnv13@gmail.com>\n * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Templates from 'core/templates';\nimport {\n    get_string as getString,\n    get_strings as getStrings,\n} from 'core/str';\nimport * as ModalFactory from 'core/modal_factory';\nimport * as ModalEvents from 'core/modal_events';\nimport {displayFilepicker} from 'editor_tiny/utils';\nimport {getCurrentLanguage, getMoodleLang} from 'editor_tiny/options';\nimport {component} from \"./common\";\nimport Modal from './embedmodal';\nimport Selectors from './selectors';\nimport {getEmbedPermissions} from './options';\n\nexport const MediaEmbed = class {\n    editor = null;\n    canShowFilePicker = false;\n\n    /**\n     * @property {Object} The names of the alignment options.\n     */\n    helpStrings = null;\n\n    /**\n     * @property {boolean} Indicate that the user is updating the media or not.\n     */\n    isUpdating = false;\n\n    /**\n     * @property {Object} The currently selected media.\n     */\n    selectedMedia = null;\n\n    constructor(editor) {\n        const permissions = getEmbedPermissions(editor);\n        this.canShowFilePicker = permissions.filepicker;\n        this.editor = editor;\n    }\n\n    async getHelpStrings() {\n        if (!this.helpStrings) {\n            const [addSource, tracks, subtitles, captions, descriptions, chapters, metadata] = await getStrings([\n                'addsource_help',\n                'tracks_help',\n                'subtitles_help',\n                'captions_help',\n                'descriptions_help',\n                'chapters_help',\n                'metadata_help',\n            ].map((key) => ({\n                key,\n                component,\n            })));\n\n            this.helpStrings = {addSource, tracks, subtitles, captions, descriptions, chapters, metadata};\n        }\n\n        return this.helpStrings;\n    }\n\n    async getTemplateContext(data) {\n        const languages = this.prepareMoodleLang();\n\n        const helpIcons = Array.from(Object.entries(await this.getHelpStrings())).forEach(([key, text]) => {\n            data[`${key.toLowerCase()}helpicon`] = {text};\n        });\n\n        return Object.assign({}, {\n            elementid: this.editor.getElement().id,\n            showfilepicker: this.canShowFilePicker,\n            langsinstalled: languages.installed,\n            langsavailable: languages.available,\n            link: true,\n            video: false,\n            audio: false,\n            isupdating: this.isUpdating,\n        }, data, helpIcons);\n    }\n\n    async displayDialogue() {\n        this.selectedMedia = this.getSelectedMedia();\n        const data = Object.assign({}, this.getCurrentEmbedData());\n        this.isUpdating = Object.keys(data).length !== 0;\n\n        const modal = await ModalFactory.create({\n            type: Modal.TYPE,\n            title: getString('createmedia', 'tiny_media'),\n            templateContext: await this.getTemplateContext(data),\n            removeOnClose: true,\n            large: true,\n        });\n\n        this.currentModal = modal;\n        await this.registerEventListeners(modal);\n        modal.show();\n    }\n\n    getCurrentEmbedData() {\n        const properties = this.getMediumProperties();\n        if (!properties) {\n            return {};\n        }\n\n        const processedProperties = {};\n        processedProperties[properties.type.toLowerCase()] = properties;\n        processedProperties.link = false;\n\n        return processedProperties;\n    }\n\n    getSelectedMedia() {\n        const mediaElm = this.editor.selection.getNode();\n\n        if (!mediaElm) {\n            return null;\n        }\n\n        if (mediaElm.nodeName.toLowerCase() === 'video' || mediaElm.nodeName.toLowerCase() === 'audio') {\n            return mediaElm;\n        }\n\n        if (mediaElm.querySelector('video')) {\n            return mediaElm.querySelector('video');\n        }\n\n        if (mediaElm.querySelector('audio')) {\n            return mediaElm.querySelector('audio');\n        }\n\n        return null;\n    }\n\n    getMediumProperties() {\n        const boolAttr = (elem, attr) => {\n            // As explained in MDL-64175, some OS (like Ubuntu), are removing the value for these attributes.\n            // So in order to check if attr=\"true\", we need to check if the attribute exists and if the value is empty or true.\n            return (elem.hasAttribute(attr) && (elem.getAttribute(attr) || elem.getAttribute(attr) === ''));\n        };\n\n        const tracks = {\n            subtitles: [],\n            captions: [],\n            descriptions: [],\n            chapters: [],\n            metadata: []\n        };\n        const sources = [];\n\n        const medium = this.selectedMedia;\n        if (!medium) {\n            return null;\n        }\n        medium.querySelectorAll('track').forEach((track) => {\n            tracks[track.getAttribute('kind')].push({\n                src: track.getAttribute('src'),\n                srclang: track.getAttribute('srclang'),\n                label: track.getAttribute('label'),\n                defaultTrack: boolAttr(track, 'default')\n            });\n        });\n\n        medium.querySelectorAll('source').forEach((source) => {\n            sources.push(source.src);\n        });\n\n        return {\n            type: medium.nodeName.toLowerCase() === 'video' ? Selectors.EMBED.mediaTypes.video : Selectors.EMBED.mediaTypes.audio,\n            sources,\n            poster: medium.getAttribute('poster'),\n            title: medium.getAttribute('title'),\n            width: medium.getAttribute('width'),\n            height: medium.getAttribute('height'),\n            autoplay: boolAttr(medium, 'autoplay'),\n            loop: boolAttr(medium, 'loop'),\n            muted: boolAttr(medium, 'muted'),\n            controls: boolAttr(medium, 'controls'),\n            tracks,\n        };\n    }\n\n    prepareMoodleLang() {\n        const moodleLangs = getMoodleLang(this.editor);\n        const currentLanguage = getCurrentLanguage(this.editor);\n\n        const installed = Object.entries(moodleLangs.installed).map(([lang, code]) => ({\n            lang,\n            code,\n            \"default\": lang === currentLanguage,\n        }));\n\n        const available = Object.entries(moodleLangs.available).map(([lang, code]) => ({\n            lang,\n            code,\n            \"default\": lang === currentLanguage,\n        }));\n\n        return {\n            installed,\n            available,\n        };\n    }\n\n    getMoodleLangObj(subtitleLang) {\n        const {available} = getMoodleLang(this.editor);\n\n        if (available[subtitleLang]) {\n            return {\n                lang: subtitleLang,\n                code: available[subtitleLang],\n            };\n        }\n\n        return null;\n    }\n\n    filePickerCallback(params, element, fpType) {\n        if (params.url !== '') {\n            const tabPane = element.closest('.tab-pane');\n            element.closest(Selectors.EMBED.elements.source).querySelector(Selectors.EMBED.elements.url).value = params.url;\n\n            if (tabPane.id === this.editor.getElement().id + '_' + Selectors.EMBED.mediaTypes.link.toLowerCase()) {\n                tabPane.querySelector(Selectors.EMBED.elements.name).value = params.file;\n            }\n\n            if (fpType === 'subtitle') {\n                // If the file is subtitle file. We need to match the language and label for that file.\n                const subtitleLang = params.file.split('.vtt')[0].split('-').slice(-1)[0];\n                const langObj = this.getMoodleLangObj(subtitleLang);\n                if (langObj) {\n                    const track = element.closest(Selectors.EMBED.elements.track);\n                    track.querySelector(Selectors.EMBED.elements.trackLabel).value = langObj.lang.trim();\n                    track.querySelector(Selectors.EMBED.elements.trackLang).value = langObj.code;\n                }\n            }\n        }\n    }\n\n    addMediaSourceComponent(element, callback) {\n        const sourceElement = element.closest(Selectors.EMBED.elements.source + Selectors.EMBED.elements.mediaSource);\n        const clone = sourceElement.cloneNode(true);\n\n        sourceElement.querySelector('.removecomponent-wrapper').classList.remove('hidden');\n        sourceElement.querySelector('.addcomponent-wrapper').classList.add('hidden');\n\n        sourceElement.parentNode.insertBefore(clone, sourceElement.nextSibling);\n\n        if (callback) {\n            callback(clone);\n        }\n    }\n\n    removeMediaSourceComponent(element) {\n        const sourceElement = element.closest(Selectors.EMBED.elements.source + Selectors.EMBED.elements.mediaSource);\n        sourceElement.remove();\n    }\n\n    addTrackComponent(element, callback) {\n        const trackElement = element.closest(Selectors.EMBED.elements.track);\n        const clone = trackElement.cloneNode(true);\n\n        trackElement.querySelector('.removecomponent-wrapper').classList.remove('hidden');\n        trackElement.querySelector('.addcomponent-wrapper').classList.add('hidden');\n\n        trackElement.parentNode.insertBefore(clone, trackElement.nextSibling);\n\n        if (callback) {\n            callback(clone);\n        }\n    }\n\n    removeTrackComponent(element) {\n        const sourceElement = element.closest(Selectors.EMBED.elements.track);\n        sourceElement.remove();\n    }\n\n    getMediumTypeFromTabPane(tabPane) {\n        return tabPane.getAttribute('data-medium-type');\n    }\n\n    getTrackTypeFromTabPane(tabPane) {\n        return tabPane.getAttribute('data-track-kind');\n    }\n\n    getMediaHTML(form) {\n        const mediumType = this.getMediumTypeFromTabPane(form.querySelector('.root.tab-content > .tab-pane.active'));\n        const tabContent = form.querySelector(Selectors.EMBED.elements[mediumType.toLowerCase() + 'Pane']);\n\n        return this['getMediaHTML' + mediumType[0].toUpperCase() + mediumType.substr(1)](tabContent);\n    }\n\n    getMediaHTMLLink(tab) {\n        const context = {\n            url: tab.querySelector(Selectors.EMBED.elements.url).value,\n            name: tab.querySelector(Selectors.EMBED.elements.name).value || false\n        };\n\n        return context.url ? Templates.renderForPromise('tiny_media/embed_media_link', context) : '';\n    }\n\n    getMediaHTMLVideo(tab) {\n        const context = this.getContextForMediaHTML(tab);\n        context.width = tab.querySelector(Selectors.EMBED.elements.width).value || false;\n        context.height = tab.querySelector(Selectors.EMBED.elements.height).value || false;\n        context.poster = tab.querySelector(\n            `${Selectors.EMBED.elements.posterSource} ${Selectors.EMBED.elements.url}`\n        ).value || false;\n\n        return context.sources.length ? Templates.renderForPromise('tiny_media/embed_media_video', context) : '';\n    }\n\n    getMediaHTMLAudio(tab) {\n        const context = this.getContextForMediaHTML(tab);\n\n        return context.sources.length ? Templates.renderForPromise('tiny_media/embed_media_audio', context) : '';\n    }\n\n    getContextForMediaHTML(tab) {\n        const tracks = Array.from(tab.querySelectorAll(Selectors.EMBED.elements.track)).map(track => ({\n            track: track.querySelector(Selectors.EMBED.elements.trackSource + ' ' + Selectors.EMBED.elements.url).value,\n            kind: this.getTrackTypeFromTabPane(track.closest('.tab-pane')),\n            label: track.querySelector(Selectors.EMBED.elements.trackLabel).value ||\n                track.querySelector(Selectors.EMBED.elements.trackLang).value,\n            srclang: track.querySelector(Selectors.EMBED.elements.trackLang).value,\n            defaultTrack: track.querySelector(Selectors.EMBED.elements.trackDefault).checked ? \"true\" : null\n        })).filter((track) => !!track.track);\n\n        const sources = Array.from(tab.querySelectorAll(Selectors.EMBED.elements.mediaSource + ' '\n            + Selectors.EMBED.elements.url))\n                .filter((source) => !!source.value)\n                .map((source) => source.value);\n\n        return {\n            sources,\n            description: tab.querySelector(Selectors.EMBED.elements.mediaSource + ' '\n                + Selectors.EMBED.elements.url).value || false,\n            tracks,\n            showControls: tab.querySelector(Selectors.EMBED.elements.mediaControl).checked,\n            autoplay: tab.querySelector(Selectors.EMBED.elements.mediaAutoplay).checked,\n            muted: tab.querySelector(Selectors.EMBED.elements.mediaMute).checked,\n            loop: tab.querySelector(Selectors.EMBED.elements.mediaLoop).checked,\n            title: tab.querySelector(Selectors.EMBED.elements.title).value || false\n        };\n    }\n\n    getFilepickerTypeFromElement(element) {\n        if (element.closest(Selectors.EMBED.elements.posterSource)) {\n            return 'image';\n        }\n        if (element.closest(Selectors.EMBED.elements.trackSource)) {\n            return 'subtitle';\n        }\n\n        return 'media';\n    }\n\n    async clickHandler(e) {\n        const element = e.target;\n\n        const mediaBrowser = element.closest(Selectors.EMBED.actions.mediaBrowser);\n        if (mediaBrowser) {\n            e.preventDefault();\n            const fpType = this.getFilepickerTypeFromElement(element);\n            const params = await displayFilepicker(this.editor, fpType);\n            this.filePickerCallback(params, element, fpType);\n        }\n\n        const addComponentSourceAction = element.closest(Selectors.EMBED.elements.mediaSource + ' .addcomponent');\n        if (addComponentSourceAction) {\n            e.preventDefault();\n            this.addMediaSourceComponent(element);\n        }\n\n        const removeComponentSourceAction = element.closest(Selectors.EMBED.elements.mediaSource + ' .removecomponent');\n        if (removeComponentSourceAction) {\n            e.preventDefault();\n            this.removeMediaSourceComponent(element);\n        }\n\n        const addComponentTrackAction = element.closest(Selectors.EMBED.elements.track + ' .addcomponent');\n        if (addComponentTrackAction) {\n            e.preventDefault();\n            this.addTrackComponent(element);\n        }\n\n        const removeComponentTrackAction = element.closest(Selectors.EMBED.elements.track + ' .removecomponent');\n        if (removeComponentTrackAction) {\n            e.preventDefault();\n            this.removeTrackComponent(element);\n        }\n\n        // Only allow one track per tab to be selected as \"default\".\n        const trackDefaultAction = element.closest(Selectors.EMBED.elements.trackDefault);\n        if (trackDefaultAction && trackDefaultAction.checked) {\n            const getKind = (el) => this.getTrackTypeFromTabPane(el.parentElement.closest('.tab-pane'));\n\n            element.parentElement\n                .closest('.root.tab-content')\n                .querySelectorAll(Selectors.EMBED.elements.trackDefault)\n                .forEach((select) => {\n                    if (select !== element && getKind(element) === getKind(select)) {\n                        select.checked = false;\n                    }\n                });\n        }\n    }\n\n    async handleDialogueSubmission(event, modal) {\n        const {html} = await this.getMediaHTML(modal.getRoot()[0]);\n        if (html) {\n            if (this.isUpdating) {\n                this.selectedMedia.outerHTML = html;\n                this.isUpdating = false;\n            } else {\n                this.editor.insertContent(html);\n            }\n        }\n    }\n\n    async registerEventListeners(modal) {\n        await modal.getBody();\n        const $root = modal.getRoot();\n        const root = $root[0];\n        if (this.canShowFilePicker) {\n            root.addEventListener('click', this.clickHandler.bind(this));\n        }\n\n        $root.on(ModalEvents.save, this.handleDialogueSubmission.bind(this));\n        $root.on(ModalEvents.hidden, () => {\n            this.currentModal.destroy();\n        });\n        $root.on(ModalEvents.shown, () => {\n            root.querySelectorAll(Selectors.EMBED.elements.trackLang).forEach((dropdown) => {\n                const defaultVal = dropdown.getAttribute('data-value');\n                if (defaultVal) {\n                    dropdown.value = defaultVal;\n                }\n            });\n        });\n    }\n};\n"],"names":["constructor","editor","permissions","canShowFilePicker","filepicker","this","helpStrings","addSource","tracks","subtitles","captions","descriptions","chapters","metadata","map","key","component","data","languages","prepareMoodleLang","helpIcons","Array","from","Object","entries","getHelpStrings","forEach","_ref","text","toLowerCase","assign","elementid","getElement","id","showfilepicker","langsinstalled","installed","langsavailable","available","link","video","audio","isupdating","isUpdating","selectedMedia","getSelectedMedia","getCurrentEmbedData","keys","length","modal","ModalFactory","create","type","Modal","TYPE","title","templateContext","getTemplateContext","removeOnClose","large","currentModal","registerEventListeners","show","properties","getMediumProperties","processedProperties","mediaElm","selection","getNode","nodeName","querySelector","boolAttr","elem","attr","hasAttribute","getAttribute","sources","medium","querySelectorAll","track","push","src","srclang","label","defaultTrack","source","Selectors","EMBED","mediaTypes","poster","width","height","autoplay","loop","muted","controls","moodleLangs","currentLanguage","_ref2","lang","code","_ref3","getMoodleLangObj","subtitleLang","filePickerCallback","params","element","fpType","url","tabPane","closest","elements","value","name","file","split","slice","langObj","trackLabel","trim","trackLang","addMediaSourceComponent","callback","sourceElement","mediaSource","clone","cloneNode","classList","remove","add","parentNode","insertBefore","nextSibling","removeMediaSourceComponent","addTrackComponent","trackElement","removeTrackComponent","getMediumTypeFromTabPane","getTrackTypeFromTabPane","getMediaHTML","form","mediumType","tabContent","toUpperCase","substr","getMediaHTMLLink","tab","context","Templates","renderForPromise","getMediaHTMLVideo","getContextForMediaHTML","posterSource","getMediaHTMLAudio","trackSource","kind","trackDefault","checked","filter","description","showControls","mediaControl","mediaAutoplay","mediaMute","mediaLoop","getFilepickerTypeFromElement","e","target","actions","mediaBrowser","preventDefault","trackDefaultAction","getKind","el","parentElement","select","event","html","getRoot","outerHTML","insertContent","getBody","$root","root","addEventListener","clickHandler","bind","on","ModalEvents","save","handleDialogueSubmission","hidden","destroy","shown","dropdown","defaultVal"],"mappings":"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"}
\ No newline at end of file
diff --git a/lib/editor/tiny/plugins/media/amd/src/embed.js b/lib/editor/tiny/plugins/media/amd/src/embed.js
index ea07415056b..be0a7488195 100644
--- a/lib/editor/tiny/plugins/media/amd/src/embed.js
+++ b/lib/editor/tiny/plugins/media/amd/src/embed.js
@@ -49,6 +49,11 @@ export const MediaEmbed = class {
      */
     isUpdating = false;
 
+    /**
+     * @property {Object} The currently selected media.
+     */
+    selectedMedia = null;
+
     constructor(editor) {
         const permissions = getEmbedPermissions(editor);
         this.canShowFilePicker = permissions.filepicker;
@@ -96,6 +101,7 @@ export const MediaEmbed = class {
     }
 
     async displayDialogue() {
+        this.selectedMedia = this.getSelectedMedia();
         const data = Object.assign({}, this.getCurrentEmbedData());
         this.isUpdating = Object.keys(data).length !== 0;
 
@@ -163,7 +169,7 @@ export const MediaEmbed = class {
         };
         const sources = [];
 
-        const medium = this.getSelectedMedia();
+        const medium = this.selectedMedia;
         if (!medium) {
             return null;
         }
@@ -425,8 +431,7 @@ export const MediaEmbed = class {
         const {html} = await this.getMediaHTML(modal.getRoot()[0]);
         if (html) {
             if (this.isUpdating) {
-                const selectedNode = this.getSelectedMedia();
-                selectedNode.outerHTML = html;
+                this.selectedMedia.outerHTML = html;
                 this.isUpdating = false;
             } else {
                 this.editor.insertContent(html);