diff --git a/lms-plugins/mediacms-moodle/tiny/mediacms/amd/build/iframeembed.min.js b/lms-plugins/mediacms-moodle/tiny/mediacms/amd/build/iframeembed.min.js index 97d61d05..601cc928 100755 --- a/lms-plugins/mediacms-moodle/tiny/mediacms/amd/build/iframeembed.min.js +++ b/lms-plugins/mediacms-moodle/tiny/mediacms/amd/build/iframeembed.min.js @@ -1,3 +1,3 @@ -define("tiny_mediacms/iframeembed",["exports","core/templates","core/str","core/modal_events","./common","./iframemodal","./selectors","./options"],(function(_exports,_templates,_str,ModalEvents,_common,_iframemodal,_selectors,_options){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 _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.default=void 0,_templates=_interopRequireDefault(_templates),ModalEvents=function(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]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(ModalEvents),_iframemodal=_interopRequireDefault(_iframemodal),_selectors=_interopRequireDefault(_selectors);return _exports.default=class{constructor(editor){_defineProperty(this,"editor",null),_defineProperty(this,"currentModal",null),_defineProperty(this,"isUpdating",!1),_defineProperty(this,"selectedIframe",null),_defineProperty(this,"debounceTimer",null),_defineProperty(this,"iframeLibraryUrl","https://temp.web357.com/mediacms/deic-mediacms-embed-videos.html"),this.editor=editor}parseInput(input){if(!input||!input.trim())return null;const iframeMatch=(input=input.trim()).match(/]*src=["']([^"']+)["'][^>]*>/i);return iframeMatch?this.parseEmbedUrl(iframeMatch[1]):input.startsWith("http://")||input.startsWith("https://")?this.parseVideoUrl(input):null}parseVideoUrl(url){try{const urlObj=new URL(url),baseUrl="".concat(urlObj.protocol,"//").concat(urlObj.host);if("/view"===urlObj.pathname&&urlObj.searchParams.has("m"))return{baseUrl:baseUrl,videoId:urlObj.searchParams.get("m"),isEmbed:!1};if("/embed"===urlObj.pathname&&urlObj.searchParams.has("m")){const tParam=urlObj.searchParams.get("t"),widthParam=urlObj.searchParams.get("width"),heightParam=urlObj.searchParams.get("height");return{baseUrl:baseUrl,videoId:urlObj.searchParams.get("m"),isEmbed:!0,showTitle:"1"===urlObj.searchParams.get("showTitle"),linkTitle:"1"===urlObj.searchParams.get("linkTitle"),showUserAvatar:"1"===urlObj.searchParams.get("showUserAvatar"),width:widthParam?parseInt(widthParam):null,height:heightParam?parseInt(heightParam):null,startAt:tParam?this.secondsToTimeString(parseInt(tParam)):null}}if(urlObj.pathname.includes("/filter/mediacms/launch.php")&&urlObj.searchParams.has("token")){const tParam=urlObj.searchParams.get("t"),widthParam=urlObj.searchParams.get("width"),heightParam=urlObj.searchParams.get("height");return{baseUrl:baseUrl,videoId:urlObj.searchParams.get("token"),rawUrl:url,isLtiLaunch:!0,showTitle:"1"===urlObj.searchParams.get("showTitle"),linkTitle:"1"===urlObj.searchParams.get("linkTitle"),showUserAvatar:"1"===urlObj.searchParams.get("showUserAvatar"),width:widthParam?parseInt(widthParam):null,height:heightParam?parseInt(heightParam):null,startAt:tParam?this.secondsToTimeString(parseInt(tParam)):null}}return{baseUrl:baseUrl,rawUrl:url,isGeneric:!0}}catch(e){return null}}parseEmbedUrl(url){return this.parseVideoUrl(url)}secondsToTimeString(seconds){const mins=Math.floor(seconds/60),secs=seconds%60;return"".concat(mins,":").concat(secs.toString().padStart(2,"0"))}timeStringToSeconds(timeStr){if(!timeStr||!timeStr.trim())return null;if((timeStr=timeStr.trim()).includes(":")){const parts=timeStr.split(":");return 60*(parseInt(parts[0])||0)+(parseInt(parts[1])||0)}const secs=parseInt(timeStr);return isNaN(secs)?null:secs}parseWidthHeight(value){if(!value)return null;const parsed=parseInt(value.trim());return isNaN(parsed)?null:parsed}computeAspectRatioCSS(values){const w=values.width||560,h=values.height||315;return"".concat(w," / ").concat(h)}buildEmbedUrl(parsed,options){if(parsed.isGeneric)return parsed.rawUrl;let url;if(parsed.isLtiLaunch){url=new URL(parsed.rawUrl);const token=url.searchParams.get("token"),courseid=url.searchParams.get("courseid");url.search="",url.searchParams.set("token",token),courseid&&url.searchParams.set("courseid",courseid)}else url=new URL("".concat(parsed.baseUrl,"/embed")),url.searchParams.set("m",parsed.videoId);if(url.searchParams.set("showTitle",options.showTitle?"1":"0"),url.searchParams.set("showUserAvatar",options.showUserAvatar?"1":"0"),url.searchParams.set("linkTitle",options.linkTitle?"1":"0"),options.startAtEnabled&&options.startAt){const seconds=this.timeStringToSeconds(options.startAt);null!==seconds&&seconds>0&&url.searchParams.set("t",seconds.toString())}return options.width&&url.searchParams.set("width",options.width),options.height&&url.searchParams.set("height",options.height),url.toString()}async getTemplateContext(){var _this=this;let data=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const editorData=(0,_options.getData)(this.editor),autoConvertOptions=(null==editorData?void 0:editorData.autoConvertOptions)||{},getDefault=function(key){let fallback=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return _this.isUpdating&&void 0!==data[key]?data[key]:void 0!==autoConvertOptions[key]?autoConvertOptions[key]:fallback},width=this.isUpdating&&data.width?data.width:560,height=this.isUpdating&&data.height?data.height:315;return{elementid:this.editor.getElement().id,isupdating:this.isUpdating,url:data.url||"",showTitle:getDefault("showTitle"),linkTitle:getDefault("linkTitle"),showUserAvatar:getDefault("showUserAvatar"),textLinkOnly:data.textLinkOnly||!1,startAtEnabled:data.startAtEnabled||!1,startAt:data.startAt||"0:00",width:width,height:height}}async displayDialogue(){this.selectedIframe=this.getSelectedIframe();const data=this.getCurrentIframeData();this.isUpdating=null!==data,this.currentModal=await _iframemodal.default.create({title:(0,_str.getString)("iframemodaltitle",_common.component),templateContext:await this.getTemplateContext(data||{})}),await this.registerEventListeners(this.currentModal)}getSelectedIframe(){const node=this.editor.selection.getNode();if("a"===node.nodeName.toLowerCase()&&"true"===node.getAttribute("data-mediacms-textlink"))return node;if("iframe"===node.nodeName.toLowerCase())return node;const iframe=node.querySelector("iframe");if(iframe)return iframe;const wrapper=node.closest(".tiny-mediacms-iframe-wrapper")||node.closest(".tiny-iframe-responsive");if(wrapper)return wrapper.querySelector("iframe");const textLink=node.closest('a[data-mediacms-textlink="true"]');return textLink||null}getCurrentIframeData(){var _parsed$showTitle2,_parsed$linkTitle2,_parsed$showUserAvata2;if(!this.selectedIframe)return null;if("a"===this.selectedIframe.nodeName.toLowerCase()&&"true"===this.selectedIframe.getAttribute("data-mediacms-textlink")){var _parsed$showTitle,_parsed$linkTitle,_parsed$showUserAvata;const href=this.selectedIframe.getAttribute("href"),parsed=this.parseInput(href);return{url:href,width:(null==parsed?void 0:parsed.width)||560,height:(null==parsed?void 0:parsed.height)||315,showTitle:null===(_parsed$showTitle=null==parsed?void 0:parsed.showTitle)||void 0===_parsed$showTitle||_parsed$showTitle,linkTitle:null===(_parsed$linkTitle=null==parsed?void 0:parsed.linkTitle)||void 0===_parsed$linkTitle||_parsed$linkTitle,showUserAvatar:null===(_parsed$showUserAvata=null==parsed?void 0:parsed.showUserAvatar)||void 0===_parsed$showUserAvata||_parsed$showUserAvata,responsive:!0,textLinkOnly:!0,startAtEnabled:null!==(null==parsed?void 0:parsed.startAt),startAt:(null==parsed?void 0:parsed.startAt)||"0:00"}}const src=this.selectedIframe.getAttribute("src"),parsed=this.parseInput(src),style=this.selectedIframe.getAttribute("style")||"",maxWidthMatch=style.match(/max-width:\s*(\d+(?:\.\d+)?)px/),aspectRatioMatch=style.match(/aspect-ratio:\s*(\d+(?:\.\d+)?)\s*\/\s*(\d+(?:\.\d+)?)/),maxWidth=maxWidthMatch?parseInt(maxWidthMatch[1]):560;let height=315;if(aspectRatioMatch){const rw=parseFloat(aspectRatioMatch[1]),rh=parseFloat(aspectRatioMatch[2]);rw>0&&(height=Math.round(maxWidth*rh/rw))}return{url:src,width:maxWidth,height:height,showTitle:null===(_parsed$showTitle2=null==parsed?void 0:parsed.showTitle)||void 0===_parsed$showTitle2||_parsed$showTitle2,linkTitle:null===(_parsed$linkTitle2=null==parsed?void 0:parsed.linkTitle)||void 0===_parsed$linkTitle2||_parsed$linkTitle2,showUserAvatar:null===(_parsed$showUserAvata2=null==parsed?void 0:parsed.showUserAvatar)||void 0===_parsed$showUserAvata2||_parsed$showUserAvata2,startAtEnabled:!(null==parsed||!parsed.startAt),startAt:(null==parsed?void 0:parsed.startAt)||"0:00"}}getFormValues(root){const form=root.querySelector(_selectors.default.IFRAME.elements.form);return{url:form.querySelector(_selectors.default.IFRAME.elements.url).value.trim(),showTitle:form.querySelector(_selectors.default.IFRAME.elements.showTitle).checked,linkTitle:form.querySelector(_selectors.default.IFRAME.elements.linkTitle).checked,showUserAvatar:form.querySelector(_selectors.default.IFRAME.elements.showUserAvatar).checked,textLinkOnly:form.querySelector(_selectors.default.IFRAME.elements.textLinkOnly).checked,startAtEnabled:form.querySelector(_selectors.default.IFRAME.elements.startAtEnabled).checked,startAt:form.querySelector(_selectors.default.IFRAME.elements.startAt).value.trim(),width:this.parseWidthHeight(form.querySelector(_selectors.default.IFRAME.elements.width).value),height:this.parseWidthHeight(form.querySelector(_selectors.default.IFRAME.elements.height).value)}}async generateIframeHtml(values){const parsed=this.parseInput(values.url);if(!parsed)return"";if(values.textLinkOnly){let viewUrl;viewUrl=parsed.isGeneric||parsed.isLtiLaunch?parsed.rawUrl:"".concat(parsed.baseUrl,"/view?m=").concat(parsed.videoId);const linkText=(str=>{const div=document.createElement("div");return div.textContent=str,div.innerHTML})(viewUrl),hrefUrl=viewUrl.replace(/"/g,""");return'

').concat(linkText,"

")}const context={src:this.buildEmbedUrl(parsed,values),maxWidth:values.width||560,height:values.height||315,aspectRatioCSS:this.computeAspectRatioCSS(values)},{html:html}=await _templates.default.renderForPromise("tiny_mediacms/iframe_embed_output",context);return html}async updatePreview(root){let updateUrlField=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const values=this.getFormValues(root),previewContainer=root.querySelector(_selectors.default.IFRAME.elements.preview),urlWarning=root.querySelector(_selectors.default.IFRAME.elements.urlWarning);if(!values.url)return previewContainer.innerHTML='Enter a video URL to see preview',void urlWarning.classList.add("d-none");const parsed=this.parseInput(values.url);if(!parsed)return previewContainer.innerHTML='Invalid URL format',void urlWarning.classList.remove("d-none");urlWarning.classList.add("d-none");const embedUrl=this.buildEmbedUrl(parsed,values);if(updateUrlField&&!parsed.isGeneric){root.querySelector(_selectors.default.IFRAME.elements.form).querySelector(_selectors.default.IFRAME.elements.url).value=embedUrl}if(values.textLinkOnly){let viewUrl;viewUrl=parsed.isGeneric||parsed.isLtiLaunch?parsed.rawUrl:"".concat(parsed.baseUrl,"/view?m=").concat(parsed.videoId);const linkText=(str=>{const div=document.createElement("div");return div.textContent=str,div.innerHTML})(viewUrl),hrefUrl=viewUrl.replace(/"/g,""");previewContainer.innerHTML='\n
\n Text link preview:
\n ').concat(linkText,"\n
\n ")}else{const previewWidth=Math.min(values.width||560,400),previewHeight=Math.round(previewWidth*(values.height||315)/(values.width||560));previewContainer.innerHTML='\n \n \n ')}}handleInputChange(root){let updateUrlField=arguments.length>1&&void 0!==arguments[1]&&arguments[1];clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout((()=>{this.updatePreview(root,updateUrlField)}),500)}handleWidthChange(root){const form=root.querySelector(_selectors.default.IFRAME.elements.form),widthInput=form.querySelector(_selectors.default.IFRAME.elements.width),heightInput=form.querySelector(_selectors.default.IFRAME.elements.height),newWidth=parseInt(widthInput.value);!isNaN(newWidth)&&newWidth>0&&(heightInput.value=Math.round(9*newWidth/16)),this.handleInputChange(root)}handleHeightChange(root){this.handleInputChange(root)}async handleDialogueSubmission(modal){const root=modal.getRoot()[0],values=this.getFormValues(root);if(!values.url)return;const html=await this.generateIframeHtml(values);if(html)if(this.isUpdating&&this.selectedIframe){const wrapper=this.selectedIframe.closest(".tiny-mediacms-iframe-wrapper")||this.selectedIframe.closest(".tiny-iframe-responsive"),paragraphWrapper=wrapper?wrapper.closest("p"):this.selectedIframe.closest("p");paragraphWrapper?paragraphWrapper.outerHTML=html:wrapper?wrapper.outerHTML=html:this.selectedIframe.outerHTML=html,this.isUpdating=!1,setTimeout((()=>{this.editor.getBody().querySelectorAll("p:empty, p:blank").forEach((p=>{""!==p.innerHTML.trim()&&"
"!==p.innerHTML||p.remove()}))}),10),this.editor.fire("Change")}else{const node=this.editor.selection.getNode();"P"===node.nodeName&&""===node.innerHTML.trim()?node.outerHTML=html:this.editor.insertContent(html),setTimeout((()=>{this.editor.getBody().querySelectorAll("p").forEach((p=>{""!==p.innerHTML.trim()&&"
"!==p.innerHTML||p.remove()}))}),50)}}async handleRemove(modal){const confirmMessage=await(0,_str.getString)("removeiframeconfirm",_common.component);if(window.confirm(confirmMessage)){if(this.selectedIframe){const wrapper=this.selectedIframe.closest(".tiny-mediacms-iframe-wrapper")||this.selectedIframe.closest(".tiny-iframe-responsive");wrapper?wrapper.remove():this.selectedIframe.remove()}this.isUpdating=!1,modal.hide()}}async registerEventListeners(modal){await modal.getBody();const $root=modal.getRoot(),root=$root[0],form=root.querySelector(_selectors.default.IFRAME.elements.form);form.querySelector(_selectors.default.IFRAME.elements.url).addEventListener("input",(()=>this.handleInputChange(root))),[_selectors.default.IFRAME.elements.showTitle,_selectors.default.IFRAME.elements.linkTitle,_selectors.default.IFRAME.elements.showUserAvatar,_selectors.default.IFRAME.elements.startAtEnabled].forEach((selector=>{form.querySelector(selector).addEventListener("change",(()=>this.handleInputChange(root,!0)))})),form.querySelector(_selectors.default.IFRAME.elements.textLinkOnly).addEventListener("change",(()=>this.handleInputChange(root,!1))),form.querySelector(_selectors.default.IFRAME.elements.startAt).addEventListener("input",(()=>this.handleInputChange(root,!0))),form.querySelector(_selectors.default.IFRAME.elements.width).addEventListener("input",(()=>this.handleWidthChange(root))),form.querySelector(_selectors.default.IFRAME.elements.height).addEventListener("input",(()=>this.handleHeightChange(root))),$root.on(ModalEvents.save,(()=>this.handleDialogueSubmission(modal))),$root.on(ModalEvents.hidden,(()=>{this.currentModal.destroy()}));const removeBtn=root.querySelector(_selectors.default.IFRAME.actions.remove);removeBtn&&removeBtn.addEventListener("click",(()=>this.handleRemove(modal)));form.querySelector(_selectors.default.IFRAME.elements.url).value&&this.updatePreview(root);const iframeLibraryTabBtn=form.querySelector(_selectors.default.IFRAME.elements.tabIframeLibraryBtn);if(iframeLibraryTabBtn){iframeLibraryTabBtn.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation(),this.switchToIframeLibraryTab(root),setTimeout((()=>this.handleIframeLibraryTabClick(root)),100)})),iframeLibraryTabBtn.addEventListener("shown.bs.tab",(()=>this.handleIframeLibraryTabClick(root)));const $iframeLibraryTabBtn=window.jQuery?window.jQuery(iframeLibraryTabBtn):null;$iframeLibraryTabBtn&&$iframeLibraryTabBtn.on("shown.bs.tab",(()=>this.handleIframeLibraryTabClick(root)))}const urlTabBtn=form.querySelector(_selectors.default.IFRAME.elements.tabUrlBtn);urlTabBtn&&urlTabBtn.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation(),this.switchToUrlTab(root)}));const uploadMediaBtn=form.querySelector(_selectors.default.IFRAME.elements.tabUploadMediaBtn);uploadMediaBtn&&uploadMediaBtn.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation(),this.switchToIframeLibraryTab(root);let uploadUrl="";const ltiConfig=(0,_options.getLti)(this.editor);if(ltiConfig&<iConfig.contentItemUrl)try{const urlObj=new URL(ltiConfig.contentItemUrl);urlObj.searchParams.set("action","upload"),uploadUrl=urlObj.toString()}catch(err){}if(!uploadUrl){let baseUrl="";try{const editorData=(0,_options.getData)(this.editor);editorData&&editorData.mediacmsBaseUrl&&(baseUrl=editorData.mediacmsBaseUrl)}catch(err){}if(!baseUrl)try{const urlObj=new URL(this.iframeLibraryUrl);baseUrl="".concat(urlObj.protocol,"//").concat(urlObj.host)}catch(err){}baseUrl=baseUrl.replace(/\/$/,""),uploadUrl=baseUrl?"".concat(baseUrl,"/upload"):""}if(uploadUrl){const pane=form.querySelector(_selectors.default.IFRAME.elements.paneIframeLibrary);if(pane){const iframeEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryFrame),placeholderEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryPlaceholder),loadingEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryLoading);if(placeholderEl&&placeholderEl.classList.add("d-none"),loadingEl&&loadingEl.classList.remove("d-none"),iframeEl){iframeEl.classList.add("d-none");const loadHandler=()=>{this.handleIframeLibraryLoad(root),iframeEl.removeEventListener("load",loadHandler)};iframeEl.addEventListener("load",loadHandler),iframeEl.src=uploadUrl}}}})),this.registerIframeLibraryEventListeners(root),this.isUpdating?setTimeout((()=>this.updatePreview(root)),100):setTimeout((()=>this.handleIframeLibraryTabClick(root)),100)}switchToUrlTab(root){const form=root.querySelector(_selectors.default.IFRAME.elements.form),urlTabBtn=form.querySelector(_selectors.default.IFRAME.elements.tabUrlBtn),urlTabItem=form.querySelector(".tiny_iframecms_tab_url_item"),iframeLibraryTabBtn=form.querySelector(_selectors.default.IFRAME.elements.tabIframeLibraryBtn),urlPane=form.querySelector(_selectors.default.IFRAME.elements.paneUrl),iframeLibraryPane=form.querySelector(_selectors.default.IFRAME.elements.paneIframeLibrary);urlTabItem&&(urlTabItem.style.display=""),urlTabBtn&&(urlTabBtn.classList.add("active"),urlTabBtn.setAttribute("aria-selected","true")),iframeLibraryTabBtn&&(iframeLibraryTabBtn.classList.remove("active"),iframeLibraryTabBtn.setAttribute("aria-selected","false")),urlPane&&urlPane.classList.add("show","active"),iframeLibraryPane&&iframeLibraryPane.classList.remove("show","active")}switchToIframeLibraryTab(root){const form=root.querySelector(_selectors.default.IFRAME.elements.form),urlTabBtn=form.querySelector(_selectors.default.IFRAME.elements.tabUrlBtn),urlTabItem=form.querySelector(".tiny_iframecms_tab_url_item"),iframeLibraryTabBtn=form.querySelector(_selectors.default.IFRAME.elements.tabIframeLibraryBtn),urlPane=form.querySelector(_selectors.default.IFRAME.elements.paneUrl),iframeLibraryPane=form.querySelector(_selectors.default.IFRAME.elements.paneIframeLibrary);urlTabItem&&(urlTabItem.style.display="none"),urlTabBtn&&(urlTabBtn.classList.remove("active"),urlTabBtn.setAttribute("aria-selected","false")),iframeLibraryTabBtn&&(iframeLibraryTabBtn.classList.add("active"),iframeLibraryTabBtn.setAttribute("aria-selected","true")),urlPane&&urlPane.classList.remove("show","active"),iframeLibraryPane&&iframeLibraryPane.classList.add("show","active")}registerIframeLibraryEventListeners(root){window.addEventListener("message",(event=>{this.handleIframeLibraryMessage(root,event)}))}handleIframeLibraryTabClick(root){this.loadIframeLibrary(root)}loadIframeLibrary(root){const ltiConfig=(0,_options.getLti)(this.editor);null!=ltiConfig&<iConfig.contentItemUrl?this.loadIframeLibraryViaLti(root):this.loadIframeLibraryStatic(root)}loadIframeLibraryViaLti(root){const pane=root.querySelector(_selectors.default.IFRAME.elements.form).querySelector(_selectors.default.IFRAME.elements.paneIframeLibrary);if(!pane)return;const placeholderEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryPlaceholder),loadingEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryLoading),iframeEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryFrame);if(!iframeEl)return;placeholderEl&&placeholderEl.classList.add("d-none"),loadingEl&&loadingEl.classList.remove("d-none"),iframeEl.classList.add("d-none");iframeEl.addEventListener("load",(()=>{this.handleIframeLibraryLoad(root)}));const ltiConfig=(0,_options.getLti)(this.editor);iframeEl.src=ltiConfig.contentItemUrl}loadIframeLibraryStatic(root){const pane=root.querySelector(_selectors.default.IFRAME.elements.form).querySelector(_selectors.default.IFRAME.elements.paneIframeLibrary);if(!pane)return;const placeholderEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryPlaceholder),loadingEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryLoading),iframeEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryFrame);if(!iframeEl)return;placeholderEl&&placeholderEl.classList.add("d-none"),loadingEl&&loadingEl.classList.remove("d-none"),iframeEl.classList.add("d-none");const loadHandler=()=>{iframeEl.src===this.iframeLibraryUrl&&(this.handleIframeLibraryLoad(root),iframeEl.removeEventListener("load",loadHandler))};iframeEl.addEventListener("load",loadHandler),iframeEl.src=this.iframeLibraryUrl}handleIframeLibraryLoad(root){const pane=root.querySelector(_selectors.default.IFRAME.elements.form).querySelector(_selectors.default.IFRAME.elements.paneIframeLibrary);if(!pane)return;const placeholderEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryPlaceholder),loadingEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryLoading),iframeEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryFrame);placeholderEl&&placeholderEl.classList.add("d-none"),loadingEl&&loadingEl.classList.add("d-none"),iframeEl&&iframeEl.classList.remove("d-none")}handleIframeLibraryMessage(root,event){const data=event.data;if(data)if("videoSelected"===data.type&&data.embedUrl)this.selectIframeLibraryVideo(root,data.embedUrl,data.videoId);else if("ltiDeepLinkingResponse"!==data.type&&"LtiDeepLinkingResponse"!==data.messageType)if("selectMedia"!==data.action&&"mediaSelected"!==data.action);else{const embedUrl=data.embedUrl||data.url||"";embedUrl&&this.selectIframeLibraryVideo(root,embedUrl)}else{const contentItems=data.content_items||data.contentItems||[];if(contentItems.length>0){const item=contentItems[0],embedUrl=item.url||item.embed_url||item.embedUrl||"",videoId=item.id||item.mediaId||"";embedUrl&&this.selectIframeLibraryVideo(root,embedUrl,videoId)}}}selectIframeLibraryVideo(root,embedUrl){root.querySelector(_selectors.default.IFRAME.elements.form).querySelector(_selectors.default.IFRAME.elements.url).value=embedUrl;const configureTabItem=root.querySelector(".tiny_iframecms_tab_url_item");configureTabItem&&(configureTabItem.style.display=""),this.switchToUrlTab(root),this.updatePreview(root)}},_exports.default})); +define("tiny_mediacms/iframeembed",["exports","core/templates","core/str","core/modal_events","./common","./iframemodal","./selectors","./options"],(function(_exports,_templates,_str,ModalEvents,_common,_iframemodal,_selectors,_options){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 _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.default=void 0,_templates=_interopRequireDefault(_templates),ModalEvents=function(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]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(ModalEvents),_iframemodal=_interopRequireDefault(_iframemodal),_selectors=_interopRequireDefault(_selectors);return _exports.default=class{constructor(editor){_defineProperty(this,"editor",null),_defineProperty(this,"currentModal",null),_defineProperty(this,"isUpdating",!1),_defineProperty(this,"selectedIframe",null),_defineProperty(this,"debounceTimer",null),_defineProperty(this,"iframeLibraryUrl","https://temp.web357.com/mediacms/deic-mediacms-embed-videos.html"),this.editor=editor}parseInput(input){if(!input||!input.trim())return null;const iframeMatch=(input=input.trim()).match(/]*src=["']([^"']+)["'][^>]*>/i);return iframeMatch?this.parseEmbedUrl(iframeMatch[1]):input.startsWith("http://")||input.startsWith("https://")?this.parseVideoUrl(input):null}parseVideoUrl(url){try{const urlObj=new URL(url),baseUrl="".concat(urlObj.protocol,"//").concat(urlObj.host);if("/view"===urlObj.pathname&&urlObj.searchParams.has("m"))return{baseUrl:baseUrl,videoId:urlObj.searchParams.get("m"),isEmbed:!1};if("/embed"===urlObj.pathname&&urlObj.searchParams.has("m")){const tParam=urlObj.searchParams.get("t"),widthParam=urlObj.searchParams.get("width"),heightParam=urlObj.searchParams.get("height");return{baseUrl:baseUrl,videoId:urlObj.searchParams.get("m"),isEmbed:!0,showTitle:"1"===urlObj.searchParams.get("showTitle"),linkTitle:"1"===urlObj.searchParams.get("linkTitle"),showUserAvatar:"1"===urlObj.searchParams.get("showUserAvatar"),width:widthParam?parseInt(widthParam):null,height:heightParam?parseInt(heightParam):null,startAt:tParam?this.secondsToTimeString(parseInt(tParam)):null}}if(urlObj.pathname.includes("/filter/mediacms/launch.php")&&urlObj.searchParams.has("token")){const tParam=urlObj.searchParams.get("t"),widthParam=urlObj.searchParams.get("width"),heightParam=urlObj.searchParams.get("height");return{baseUrl:baseUrl,videoId:urlObj.searchParams.get("token"),rawUrl:url,isLtiLaunch:!0,showTitle:"1"===urlObj.searchParams.get("showTitle"),linkTitle:"1"===urlObj.searchParams.get("linkTitle"),showUserAvatar:"1"===urlObj.searchParams.get("showUserAvatar"),width:widthParam?parseInt(widthParam):null,height:heightParam?parseInt(heightParam):null,startAt:tParam?this.secondsToTimeString(parseInt(tParam)):null}}return{baseUrl:baseUrl,rawUrl:url,isGeneric:!0}}catch(e){return null}}parseEmbedUrl(url){return this.parseVideoUrl(url)}secondsToTimeString(seconds){const mins=Math.floor(seconds/60),secs=seconds%60;return"".concat(mins,":").concat(secs.toString().padStart(2,"0"))}timeStringToSeconds(timeStr){if(!timeStr||!timeStr.trim())return null;if((timeStr=timeStr.trim()).includes(":")){const parts=timeStr.split(":");return 60*(parseInt(parts[0])||0)+(parseInt(parts[1])||0)}const secs=parseInt(timeStr);return isNaN(secs)?null:secs}parseWidthHeight(value){if(!value)return null;const parsed=parseInt(value.trim());return isNaN(parsed)?null:parsed}computeAspectRatioCSS(values){const w=values.width||560,h=values.height||315;return"".concat(w," / ").concat(h)}buildEmbedUrl(parsed,options){if(parsed.isGeneric)return parsed.rawUrl;let url;if(parsed.isLtiLaunch){url=new URL(parsed.rawUrl);const token=url.searchParams.get("token"),courseid=url.searchParams.get("courseid");url.search="",url.searchParams.set("token",token),courseid&&url.searchParams.set("courseid",courseid)}else url=new URL("".concat(parsed.baseUrl,"/embed")),url.searchParams.set("m",parsed.videoId);if(url.searchParams.set("showTitle",options.showTitle?"1":"0"),url.searchParams.set("showUserAvatar",options.showUserAvatar?"1":"0"),url.searchParams.set("linkTitle",options.linkTitle?"1":"0"),options.startAtEnabled&&options.startAt){const seconds=this.timeStringToSeconds(options.startAt);null!==seconds&&seconds>0&&url.searchParams.set("t",seconds.toString())}return options.width&&url.searchParams.set("width",options.width),options.height&&url.searchParams.set("height",options.height),url.toString()}async getTemplateContext(){var _this=this;let data=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const editorData=(0,_options.getData)(this.editor),autoConvertOptions=(null==editorData?void 0:editorData.autoConvertOptions)||{},getDefault=function(key){let fallback=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return _this.isUpdating&&void 0!==data[key]?data[key]:void 0!==autoConvertOptions[key]?autoConvertOptions[key]:fallback},width=this.isUpdating&&data.width?data.width:560,height=this.isUpdating&&data.height?data.height:315;return{elementid:this.editor.getElement().id,isupdating:this.isUpdating,url:data.url||"",showTitle:getDefault("showTitle"),linkTitle:getDefault("linkTitle"),showUserAvatar:getDefault("showUserAvatar"),textLinkOnly:data.textLinkOnly||!1,startAtEnabled:data.startAtEnabled||!1,startAt:data.startAt||"0:00",width:width,height:height}}async displayDialogue(){this.selectedIframe=this.getSelectedIframe();const data=this.getCurrentIframeData();this.isUpdating=null!==data,this.currentModal=await _iframemodal.default.create({title:(0,_str.getString)("iframemodaltitle",_common.component),templateContext:await this.getTemplateContext(data||{})}),await this.registerEventListeners(this.currentModal)}getSelectedIframe(){const node=this.editor.selection.getNode();if("a"===node.nodeName.toLowerCase()&&"true"===node.getAttribute("data-mediacms-textlink"))return node;if("iframe"===node.nodeName.toLowerCase())return node;const iframe=node.querySelector("iframe");if(iframe)return iframe;const wrapper=node.closest(".tiny-mediacms-iframe-wrapper")||node.closest(".tiny-iframe-responsive");if(wrapper)return wrapper.querySelector("iframe");const textLink=node.closest('a[data-mediacms-textlink="true"]');return textLink||null}getCurrentIframeData(){var _parsed$showTitle2,_parsed$linkTitle2,_parsed$showUserAvata2;if(!this.selectedIframe)return null;if("a"===this.selectedIframe.nodeName.toLowerCase()&&"true"===this.selectedIframe.getAttribute("data-mediacms-textlink")){var _parsed$showTitle,_parsed$linkTitle,_parsed$showUserAvata;const href=this.selectedIframe.getAttribute("href"),parsed=this.parseInput(href);return{url:href,width:(null==parsed?void 0:parsed.width)||560,height:(null==parsed?void 0:parsed.height)||315,showTitle:null===(_parsed$showTitle=null==parsed?void 0:parsed.showTitle)||void 0===_parsed$showTitle||_parsed$showTitle,linkTitle:null===(_parsed$linkTitle=null==parsed?void 0:parsed.linkTitle)||void 0===_parsed$linkTitle||_parsed$linkTitle,showUserAvatar:null===(_parsed$showUserAvata=null==parsed?void 0:parsed.showUserAvatar)||void 0===_parsed$showUserAvata||_parsed$showUserAvata,responsive:!0,textLinkOnly:!0,startAtEnabled:null!==(null==parsed?void 0:parsed.startAt),startAt:(null==parsed?void 0:parsed.startAt)||"0:00"}}const src=this.selectedIframe.getAttribute("src"),parsed=this.parseInput(src),style=this.selectedIframe.getAttribute("style")||"",maxWidthMatch=style.match(/max-width:\s*(\d+(?:\.\d+)?)px/),aspectRatioMatch=style.match(/aspect-ratio:\s*(\d+(?:\.\d+)?)\s*\/\s*(\d+(?:\.\d+)?)/);let maxWidth=maxWidthMatch?parseInt(maxWidthMatch[1]):null;if(!maxWidth){const wrapper=this.selectedIframe.closest(".tiny-mediacms-iframe-wrapper"),wrapperMatch=(wrapper&&wrapper.getAttribute("style")||"").match(/max-width:\s*(\d+(?:\.\d+)?)px/);maxWidth=wrapperMatch?parseInt(wrapperMatch[1]):560}let height=315;if(aspectRatioMatch){const rw=parseFloat(aspectRatioMatch[1]),rh=parseFloat(aspectRatioMatch[2]);rw>0&&(height=Math.round(maxWidth*rh/rw))}return{url:src,width:maxWidth,height:height,showTitle:null===(_parsed$showTitle2=null==parsed?void 0:parsed.showTitle)||void 0===_parsed$showTitle2||_parsed$showTitle2,linkTitle:null===(_parsed$linkTitle2=null==parsed?void 0:parsed.linkTitle)||void 0===_parsed$linkTitle2||_parsed$linkTitle2,showUserAvatar:null===(_parsed$showUserAvata2=null==parsed?void 0:parsed.showUserAvatar)||void 0===_parsed$showUserAvata2||_parsed$showUserAvata2,startAtEnabled:!(null==parsed||!parsed.startAt),startAt:(null==parsed?void 0:parsed.startAt)||"0:00"}}getFormValues(root){const form=root.querySelector(_selectors.default.IFRAME.elements.form);return{url:form.querySelector(_selectors.default.IFRAME.elements.url).value.trim(),showTitle:form.querySelector(_selectors.default.IFRAME.elements.showTitle).checked,linkTitle:form.querySelector(_selectors.default.IFRAME.elements.linkTitle).checked,showUserAvatar:form.querySelector(_selectors.default.IFRAME.elements.showUserAvatar).checked,textLinkOnly:form.querySelector(_selectors.default.IFRAME.elements.textLinkOnly).checked,startAtEnabled:form.querySelector(_selectors.default.IFRAME.elements.startAtEnabled).checked,startAt:form.querySelector(_selectors.default.IFRAME.elements.startAt).value.trim(),width:this.parseWidthHeight(form.querySelector(_selectors.default.IFRAME.elements.width).value),height:this.parseWidthHeight(form.querySelector(_selectors.default.IFRAME.elements.height).value)}}async generateIframeHtml(values){const parsed=this.parseInput(values.url);if(!parsed)return"";if(values.textLinkOnly){let viewUrl;viewUrl=parsed.isGeneric||parsed.isLtiLaunch?parsed.rawUrl:"".concat(parsed.baseUrl,"/view?m=").concat(parsed.videoId);const linkText=(str=>{const div=document.createElement("div");return div.textContent=str,div.innerHTML})(viewUrl),hrefUrl=viewUrl.replace(/"/g,""");return'

').concat(linkText,"

")}const context={src:this.buildEmbedUrl(parsed,values),maxWidth:values.width||560,height:values.height||315,aspectRatioCSS:this.computeAspectRatioCSS(values)},{html:html}=await _templates.default.renderForPromise("tiny_mediacms/iframe_embed_output",context);return html}async updatePreview(root){let updateUrlField=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const values=this.getFormValues(root),previewContainer=root.querySelector(_selectors.default.IFRAME.elements.preview),urlWarning=root.querySelector(_selectors.default.IFRAME.elements.urlWarning);if(!values.url)return previewContainer.innerHTML='Enter a video URL to see preview',void urlWarning.classList.add("d-none");const parsed=this.parseInput(values.url);if(!parsed)return previewContainer.innerHTML='Invalid URL format',void urlWarning.classList.remove("d-none");urlWarning.classList.add("d-none");const embedUrl=this.buildEmbedUrl(parsed,values);if(updateUrlField&&!parsed.isGeneric){root.querySelector(_selectors.default.IFRAME.elements.form).querySelector(_selectors.default.IFRAME.elements.url).value=embedUrl}if(values.textLinkOnly){let viewUrl;viewUrl=parsed.isGeneric||parsed.isLtiLaunch?parsed.rawUrl:"".concat(parsed.baseUrl,"/view?m=").concat(parsed.videoId);const linkText=(str=>{const div=document.createElement("div");return div.textContent=str,div.innerHTML})(viewUrl),hrefUrl=viewUrl.replace(/"/g,""");previewContainer.innerHTML='\n
\n Text link preview:
\n ').concat(linkText,"\n
\n ")}else{const previewWidth=Math.min(values.width||560,400),previewHeight=Math.round(previewWidth*(values.height||315)/(values.width||560));previewContainer.innerHTML='\n \n \n ')}}handleInputChange(root){let updateUrlField=arguments.length>1&&void 0!==arguments[1]&&arguments[1];clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout((()=>{this.updatePreview(root,updateUrlField)}),500)}handleWidthChange(root){const form=root.querySelector(_selectors.default.IFRAME.elements.form),widthInput=form.querySelector(_selectors.default.IFRAME.elements.width),heightInput=form.querySelector(_selectors.default.IFRAME.elements.height),newWidth=parseInt(widthInput.value);!isNaN(newWidth)&&newWidth>0&&(heightInput.value=Math.round(9*newWidth/16)),this.handleInputChange(root)}handleHeightChange(root){this.handleInputChange(root)}async handleDialogueSubmission(modal){const root=modal.getRoot()[0],values=this.getFormValues(root);if(!values.url)return;const html=await this.generateIframeHtml(values);if(html)if(this.isUpdating&&this.selectedIframe){const wrapper=this.selectedIframe.closest(".tiny-mediacms-iframe-wrapper")||this.selectedIframe.closest(".tiny-iframe-responsive"),paragraphWrapper=wrapper?wrapper.closest("p"):this.selectedIframe.closest("p");paragraphWrapper?paragraphWrapper.outerHTML=html:wrapper?wrapper.outerHTML=html:this.selectedIframe.outerHTML=html,this.isUpdating=!1,setTimeout((()=>{this.editor.getBody().querySelectorAll("p:empty, p:blank").forEach((p=>{""!==p.innerHTML.trim()&&"
"!==p.innerHTML||p.remove()}))}),10),this.editor.fire("Change")}else{const node=this.editor.selection.getNode();"P"===node.nodeName&&""===node.innerHTML.trim()?node.outerHTML=html:this.editor.insertContent(html),setTimeout((()=>{this.editor.getBody().querySelectorAll("p").forEach((p=>{""!==p.innerHTML.trim()&&"
"!==p.innerHTML||p.remove()}))}),50)}}async handleRemove(modal){const confirmMessage=await(0,_str.getString)("removeiframeconfirm",_common.component);if(window.confirm(confirmMessage)){if(this.selectedIframe){const wrapper=this.selectedIframe.closest(".tiny-mediacms-iframe-wrapper")||this.selectedIframe.closest(".tiny-iframe-responsive");wrapper?wrapper.remove():this.selectedIframe.remove()}this.isUpdating=!1,modal.hide()}}async registerEventListeners(modal){await modal.getBody();const $root=modal.getRoot(),root=$root[0],form=root.querySelector(_selectors.default.IFRAME.elements.form);form.querySelector(_selectors.default.IFRAME.elements.url).addEventListener("input",(()=>this.handleInputChange(root))),[_selectors.default.IFRAME.elements.showTitle,_selectors.default.IFRAME.elements.linkTitle,_selectors.default.IFRAME.elements.showUserAvatar,_selectors.default.IFRAME.elements.startAtEnabled].forEach((selector=>{form.querySelector(selector).addEventListener("change",(()=>this.handleInputChange(root,!0)))})),form.querySelector(_selectors.default.IFRAME.elements.textLinkOnly).addEventListener("change",(()=>this.handleInputChange(root,!1))),form.querySelector(_selectors.default.IFRAME.elements.startAt).addEventListener("input",(()=>this.handleInputChange(root,!0))),form.querySelector(_selectors.default.IFRAME.elements.width).addEventListener("input",(()=>this.handleWidthChange(root))),form.querySelector(_selectors.default.IFRAME.elements.height).addEventListener("input",(()=>this.handleHeightChange(root))),$root.on(ModalEvents.save,(()=>this.handleDialogueSubmission(modal))),$root.on(ModalEvents.hidden,(()=>{this.currentModal.destroy()}));const removeBtn=root.querySelector(_selectors.default.IFRAME.actions.remove);removeBtn&&removeBtn.addEventListener("click",(()=>this.handleRemove(modal)));form.querySelector(_selectors.default.IFRAME.elements.url).value&&this.updatePreview(root);const iframeLibraryTabBtn=form.querySelector(_selectors.default.IFRAME.elements.tabIframeLibraryBtn);if(iframeLibraryTabBtn){iframeLibraryTabBtn.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation(),this.switchToIframeLibraryTab(root),setTimeout((()=>this.handleIframeLibraryTabClick(root)),100)})),iframeLibraryTabBtn.addEventListener("shown.bs.tab",(()=>this.handleIframeLibraryTabClick(root)));const $iframeLibraryTabBtn=window.jQuery?window.jQuery(iframeLibraryTabBtn):null;$iframeLibraryTabBtn&&$iframeLibraryTabBtn.on("shown.bs.tab",(()=>this.handleIframeLibraryTabClick(root)))}const urlTabBtn=form.querySelector(_selectors.default.IFRAME.elements.tabUrlBtn);urlTabBtn&&urlTabBtn.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation(),this.switchToUrlTab(root)}));const uploadMediaBtn=form.querySelector(_selectors.default.IFRAME.elements.tabUploadMediaBtn);uploadMediaBtn&&uploadMediaBtn.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation(),this.switchToIframeLibraryTab(root);let uploadUrl="";const ltiConfig=(0,_options.getLti)(this.editor);if(ltiConfig&<iConfig.contentItemUrl)try{const urlObj=new URL(ltiConfig.contentItemUrl);urlObj.searchParams.set("action","upload"),uploadUrl=urlObj.toString()}catch(err){}if(!uploadUrl){let baseUrl="";try{const editorData=(0,_options.getData)(this.editor);editorData&&editorData.mediacmsBaseUrl&&(baseUrl=editorData.mediacmsBaseUrl)}catch(err){}if(!baseUrl)try{const urlObj=new URL(this.iframeLibraryUrl);baseUrl="".concat(urlObj.protocol,"//").concat(urlObj.host)}catch(err){}baseUrl=baseUrl.replace(/\/$/,""),uploadUrl=baseUrl?"".concat(baseUrl,"/upload"):""}if(uploadUrl){const pane=form.querySelector(_selectors.default.IFRAME.elements.paneIframeLibrary);if(pane){const iframeEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryFrame),placeholderEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryPlaceholder),loadingEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryLoading);if(placeholderEl&&placeholderEl.classList.add("d-none"),loadingEl&&loadingEl.classList.remove("d-none"),iframeEl){iframeEl.classList.add("d-none");const loadHandler=()=>{this.handleIframeLibraryLoad(root),iframeEl.removeEventListener("load",loadHandler)};iframeEl.addEventListener("load",loadHandler),iframeEl.src=uploadUrl}}}})),this.registerIframeLibraryEventListeners(root),this.isUpdating?setTimeout((()=>this.updatePreview(root)),100):setTimeout((()=>this.handleIframeLibraryTabClick(root)),100)}switchToUrlTab(root){const form=root.querySelector(_selectors.default.IFRAME.elements.form),urlTabBtn=form.querySelector(_selectors.default.IFRAME.elements.tabUrlBtn),urlTabItem=form.querySelector(".tiny_iframecms_tab_url_item"),iframeLibraryTabBtn=form.querySelector(_selectors.default.IFRAME.elements.tabIframeLibraryBtn),urlPane=form.querySelector(_selectors.default.IFRAME.elements.paneUrl),iframeLibraryPane=form.querySelector(_selectors.default.IFRAME.elements.paneIframeLibrary);urlTabItem&&(urlTabItem.style.display=""),urlTabBtn&&(urlTabBtn.classList.add("active"),urlTabBtn.setAttribute("aria-selected","true")),iframeLibraryTabBtn&&(iframeLibraryTabBtn.classList.remove("active"),iframeLibraryTabBtn.setAttribute("aria-selected","false")),urlPane&&urlPane.classList.add("show","active"),iframeLibraryPane&&iframeLibraryPane.classList.remove("show","active")}switchToIframeLibraryTab(root){const form=root.querySelector(_selectors.default.IFRAME.elements.form),urlTabBtn=form.querySelector(_selectors.default.IFRAME.elements.tabUrlBtn),urlTabItem=form.querySelector(".tiny_iframecms_tab_url_item"),iframeLibraryTabBtn=form.querySelector(_selectors.default.IFRAME.elements.tabIframeLibraryBtn),urlPane=form.querySelector(_selectors.default.IFRAME.elements.paneUrl),iframeLibraryPane=form.querySelector(_selectors.default.IFRAME.elements.paneIframeLibrary);urlTabItem&&(urlTabItem.style.display="none"),urlTabBtn&&(urlTabBtn.classList.remove("active"),urlTabBtn.setAttribute("aria-selected","false")),iframeLibraryTabBtn&&(iframeLibraryTabBtn.classList.add("active"),iframeLibraryTabBtn.setAttribute("aria-selected","true")),urlPane&&urlPane.classList.remove("show","active"),iframeLibraryPane&&iframeLibraryPane.classList.add("show","active")}registerIframeLibraryEventListeners(root){window.addEventListener("message",(event=>{this.handleIframeLibraryMessage(root,event)}))}handleIframeLibraryTabClick(root){this.loadIframeLibrary(root)}loadIframeLibrary(root){const ltiConfig=(0,_options.getLti)(this.editor);null!=ltiConfig&<iConfig.contentItemUrl?this.loadIframeLibraryViaLti(root):this.loadIframeLibraryStatic(root)}loadIframeLibraryViaLti(root){const pane=root.querySelector(_selectors.default.IFRAME.elements.form).querySelector(_selectors.default.IFRAME.elements.paneIframeLibrary);if(!pane)return;const placeholderEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryPlaceholder),loadingEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryLoading),iframeEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryFrame);if(!iframeEl)return;placeholderEl&&placeholderEl.classList.add("d-none"),loadingEl&&loadingEl.classList.remove("d-none"),iframeEl.classList.add("d-none");iframeEl.addEventListener("load",(()=>{this.handleIframeLibraryLoad(root)}));const ltiConfig=(0,_options.getLti)(this.editor);iframeEl.src=ltiConfig.contentItemUrl}loadIframeLibraryStatic(root){const pane=root.querySelector(_selectors.default.IFRAME.elements.form).querySelector(_selectors.default.IFRAME.elements.paneIframeLibrary);if(!pane)return;const placeholderEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryPlaceholder),loadingEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryLoading),iframeEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryFrame);if(!iframeEl)return;placeholderEl&&placeholderEl.classList.add("d-none"),loadingEl&&loadingEl.classList.remove("d-none"),iframeEl.classList.add("d-none");const loadHandler=()=>{iframeEl.src===this.iframeLibraryUrl&&(this.handleIframeLibraryLoad(root),iframeEl.removeEventListener("load",loadHandler))};iframeEl.addEventListener("load",loadHandler),iframeEl.src=this.iframeLibraryUrl}handleIframeLibraryLoad(root){const pane=root.querySelector(_selectors.default.IFRAME.elements.form).querySelector(_selectors.default.IFRAME.elements.paneIframeLibrary);if(!pane)return;const placeholderEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryPlaceholder),loadingEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryLoading),iframeEl=pane.querySelector(_selectors.default.IFRAME.elements.iframeLibraryFrame);placeholderEl&&placeholderEl.classList.add("d-none"),loadingEl&&loadingEl.classList.add("d-none"),iframeEl&&iframeEl.classList.remove("d-none")}handleIframeLibraryMessage(root,event){const data=event.data;if(data)if("videoSelected"===data.type&&data.embedUrl)this.selectIframeLibraryVideo(root,data.embedUrl,data.videoId);else if("ltiDeepLinkingResponse"!==data.type&&"LtiDeepLinkingResponse"!==data.messageType)if("selectMedia"!==data.action&&"mediaSelected"!==data.action);else{const embedUrl=data.embedUrl||data.url||"";embedUrl&&this.selectIframeLibraryVideo(root,embedUrl)}else{const contentItems=data.content_items||data.contentItems||[];if(contentItems.length>0){const item=contentItems[0],embedUrl=item.url||item.embed_url||item.embedUrl||"",videoId=item.id||item.mediaId||"";embedUrl&&this.selectIframeLibraryVideo(root,embedUrl,videoId)}}}selectIframeLibraryVideo(root,embedUrl){root.querySelector(_selectors.default.IFRAME.elements.form).querySelector(_selectors.default.IFRAME.elements.url).value=embedUrl;const configureTabItem=root.querySelector(".tiny_iframecms_tab_url_item");configureTabItem&&(configureTabItem.style.display=""),this.switchToUrlTab(root),this.updatePreview(root)}},_exports.default})); //# sourceMappingURL=iframeembed.min.js.map \ No newline at end of file diff --git a/lms-plugins/mediacms-moodle/tiny/mediacms/amd/build/iframeembed.min.js.map b/lms-plugins/mediacms-moodle/tiny/mediacms/amd/build/iframeembed.min.js.map index 0e7d7f39..30252b35 100755 --- a/lms-plugins/mediacms-moodle/tiny/mediacms/amd/build/iframeembed.min.js.map +++ b/lms-plugins/mediacms-moodle/tiny/mediacms/amd/build/iframeembed.min.js.map @@ -1 +1 @@ -{"version":3,"file":"iframeembed.min.js","sources":["../src/iframeembed.js"],"sourcesContent":["import Templates from 'core/templates';\nimport { getString } from 'core/str';\nimport * as ModalEvents from 'core/modal_events';\nimport { component } from './common';\nimport IframeModal from './iframemodal';\nimport Selectors from './selectors';\nimport { getLti, getData } from './options';\n\nexport default class IframeEmbed {\n editor = null;\n currentModal = null;\n isUpdating = false;\n selectedIframe = null;\n debounceTimer = null;\n iframeLibraryUrl =\n 'https://temp.web357.com/mediacms/deic-mediacms-embed-videos.html';\n\n constructor(editor) {\n this.editor = editor;\n }\n\n parseInput(input) {\n if (!input || !input.trim()) {\n return null;\n }\n\n input = input.trim();\n\n const iframeMatch = input.match(\n /]*src=[\"']([^\"']+)[\"'][^>]*>/i,\n );\n if (iframeMatch) {\n return this.parseEmbedUrl(iframeMatch[1]);\n }\n\n if (input.startsWith('http://') || input.startsWith('https://')) {\n return this.parseVideoUrl(input);\n }\n\n return null;\n }\n\n parseVideoUrl(url) {\n try {\n const urlObj = new URL(url);\n const baseUrl = `${urlObj.protocol}//${urlObj.host}`;\n\n if (urlObj.pathname === '/view' && urlObj.searchParams.has('m')) {\n return {\n baseUrl: baseUrl,\n videoId: urlObj.searchParams.get('m'),\n isEmbed: false,\n };\n }\n\n if (urlObj.pathname === '/embed' && urlObj.searchParams.has('m')) {\n const tParam = urlObj.searchParams.get('t');\n const widthParam = urlObj.searchParams.get('width');\n const heightParam = urlObj.searchParams.get('height');\n return {\n baseUrl: baseUrl,\n videoId: urlObj.searchParams.get('m'),\n isEmbed: true,\n showTitle: urlObj.searchParams.get('showTitle') === '1',\n linkTitle: urlObj.searchParams.get('linkTitle') === '1',\n showUserAvatar:\n urlObj.searchParams.get('showUserAvatar') === '1',\n width: widthParam ? parseInt(widthParam) : null,\n height: heightParam ? parseInt(heightParam) : null,\n startAt: tParam\n ? this.secondsToTimeString(parseInt(tParam))\n : null,\n };\n }\n\n if (urlObj.pathname.includes('/filter/mediacms/launch.php') && urlObj.searchParams.has('token')) {\n const tParam = urlObj.searchParams.get('t');\n const widthParam = urlObj.searchParams.get('width');\n const heightParam = urlObj.searchParams.get('height');\n\n return {\n baseUrl: baseUrl,\n videoId: urlObj.searchParams.get('token'),\n rawUrl: url,\n isLtiLaunch: true,\n showTitle: urlObj.searchParams.get('showTitle') === '1',\n linkTitle: urlObj.searchParams.get('linkTitle') === '1',\n showUserAvatar: urlObj.searchParams.get('showUserAvatar') === '1',\n width: widthParam ? parseInt(widthParam) : null,\n height: heightParam ? parseInt(heightParam) : null,\n startAt: tParam ? this.secondsToTimeString(parseInt(tParam)) : null,\n };\n }\n\n return {\n baseUrl: baseUrl,\n rawUrl: url,\n isGeneric: true,\n };\n } catch (e) {\n return null;\n }\n }\n\n parseEmbedUrl(url) {\n return this.parseVideoUrl(url);\n }\n\n secondsToTimeString(seconds) {\n const mins = Math.floor(seconds / 60);\n const secs = seconds % 60;\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n }\n\n timeStringToSeconds(timeStr) {\n if (!timeStr || !timeStr.trim()) {\n return null;\n }\n timeStr = timeStr.trim();\n\n if (timeStr.includes(':')) {\n const parts = timeStr.split(':');\n const mins = parseInt(parts[0]) || 0;\n const secs = parseInt(parts[1]) || 0;\n return mins * 60 + secs;\n }\n\n const secs = parseInt(timeStr);\n return isNaN(secs) ? null : secs;\n }\n\n parseWidthHeight(value) {\n if (!value) {\n return null;\n }\n const parsed = parseInt(value.trim());\n return isNaN(parsed) ? null : parsed;\n }\n\n computeAspectRatioCSS(values) {\n const w = values.width || 560;\n const h = values.height || 315;\n return `${w} / ${h}`;\n }\n\n buildEmbedUrl(parsed, options) {\n if (parsed.isGeneric) {\n return parsed.rawUrl;\n }\n\n let url;\n if (parsed.isLtiLaunch) {\n url = new URL(parsed.rawUrl);\n const token = url.searchParams.get('token');\n const courseid = url.searchParams.get('courseid');\n url.search = '';\n url.searchParams.set('token', token);\n if (courseid) {\n url.searchParams.set('courseid', courseid);\n }\n } else {\n url = new URL(`${parsed.baseUrl}/embed`);\n url.searchParams.set('m', parsed.videoId);\n }\n\n url.searchParams.set('showTitle', options.showTitle ? '1' : '0');\n url.searchParams.set(\n 'showUserAvatar',\n options.showUserAvatar ? '1' : '0',\n );\n url.searchParams.set('linkTitle', options.linkTitle ? '1' : '0');\n\n if (options.startAtEnabled && options.startAt) {\n const seconds = this.timeStringToSeconds(options.startAt);\n if (seconds !== null && seconds > 0) {\n url.searchParams.set('t', seconds.toString());\n }\n }\n\n if (options.width) {\n url.searchParams.set('width', options.width);\n }\n if (options.height) {\n url.searchParams.set('height', options.height);\n }\n\n return url.toString();\n }\n\n async getTemplateContext(data = {}) {\n const editorData = getData(this.editor);\n const autoConvertOptions = editorData?.autoConvertOptions || {};\n\n const getDefault = (key, fallback = true) => {\n if (this.isUpdating && data[key] !== undefined) {\n return data[key];\n }\n return autoConvertOptions[key] !== undefined\n ? autoConvertOptions[key]\n : fallback;\n };\n\n const width = (this.isUpdating && data.width) ? data.width : 560;\n const height = (this.isUpdating && data.height) ? data.height : 315;\n\n return {\n elementid: this.editor.getElement().id,\n isupdating: this.isUpdating,\n url: data.url || '',\n showTitle: getDefault('showTitle'),\n linkTitle: getDefault('linkTitle'),\n showUserAvatar: getDefault('showUserAvatar'),\n textLinkOnly: data.textLinkOnly || false,\n startAtEnabled: data.startAtEnabled || false,\n startAt: data.startAt || '0:00',\n width,\n height,\n };\n }\n\n async displayDialogue() {\n this.selectedIframe = this.getSelectedIframe();\n const data = this.getCurrentIframeData();\n this.isUpdating = data !== null;\n\n this.currentModal = await IframeModal.create({\n title: getString('iframemodaltitle', component),\n templateContext: await this.getTemplateContext(data || {}),\n });\n\n await this.registerEventListeners(this.currentModal);\n }\n\n getSelectedIframe() {\n const node = this.editor.selection.getNode();\n\n if (node.nodeName.toLowerCase() === 'a' && node.getAttribute('data-mediacms-textlink') === 'true') {\n return node;\n }\n\n if (node.nodeName.toLowerCase() === 'iframe') {\n return node;\n }\n\n const iframe = node.querySelector('iframe');\n if (iframe) {\n return iframe;\n }\n\n const wrapper =\n node.closest('.tiny-mediacms-iframe-wrapper') ||\n node.closest('.tiny-iframe-responsive');\n if (wrapper) {\n return wrapper.querySelector('iframe');\n }\n\n const textLink = node.closest('a[data-mediacms-textlink=\"true\"]');\n if (textLink) {\n return textLink;\n }\n\n return null;\n }\n\n getCurrentIframeData() {\n if (!this.selectedIframe) {\n return null;\n }\n\n if (this.selectedIframe.nodeName.toLowerCase() === 'a' &&\n this.selectedIframe.getAttribute('data-mediacms-textlink') === 'true') {\n const href = this.selectedIframe.getAttribute('href');\n const parsed = this.parseInput(href);\n\n return {\n url: href,\n width: parsed?.width || 560,\n height: parsed?.height || 315,\n showTitle: parsed?.showTitle ?? true,\n linkTitle: parsed?.linkTitle ?? true,\n showUserAvatar: parsed?.showUserAvatar ?? true,\n responsive: true,\n textLinkOnly: true,\n startAtEnabled: parsed?.startAt !== null,\n startAt: parsed?.startAt || '0:00',\n };\n }\n\n const src = this.selectedIframe.getAttribute('src');\n const parsed = this.parseInput(src);\n\n // Parse responsive dimensions from inline style\n const style = this.selectedIframe.getAttribute('style') || '';\n const maxWidthMatch = style.match(/max-width:\\s*(\\d+(?:\\.\\d+)?)px/);\n const aspectRatioMatch = style.match(/aspect-ratio:\\s*(\\d+(?:\\.\\d+)?)\\s*\\/\\s*(\\d+(?:\\.\\d+)?)/);\n\n const maxWidth = maxWidthMatch ? parseInt(maxWidthMatch[1]) : 560;\n let height = 315;\n\n if (aspectRatioMatch) {\n const rw = parseFloat(aspectRatioMatch[1]);\n const rh = parseFloat(aspectRatioMatch[2]);\n if (rw > 0) {\n height = Math.round(maxWidth * rh / rw);\n }\n }\n\n return {\n url: src,\n width: maxWidth,\n height,\n showTitle: parsed?.showTitle ?? true,\n linkTitle: parsed?.linkTitle ?? true,\n showUserAvatar: parsed?.showUserAvatar ?? true,\n startAtEnabled: !!(parsed?.startAt),\n startAt: parsed?.startAt || '0:00',\n };\n }\n\n getFormValues(root) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n\n return {\n url: form.querySelector(Selectors.IFRAME.elements.url).value.trim(),\n showTitle: form.querySelector(Selectors.IFRAME.elements.showTitle)\n .checked,\n linkTitle: form.querySelector(Selectors.IFRAME.elements.linkTitle)\n .checked,\n showUserAvatar: form.querySelector(\n Selectors.IFRAME.elements.showUserAvatar,\n ).checked,\n textLinkOnly: form.querySelector(Selectors.IFRAME.elements.textLinkOnly)\n .checked,\n startAtEnabled: form.querySelector(\n Selectors.IFRAME.elements.startAtEnabled,\n ).checked,\n startAt: form\n .querySelector(Selectors.IFRAME.elements.startAt)\n .value.trim(),\n width: this.parseWidthHeight(\n form.querySelector(Selectors.IFRAME.elements.width).value,\n ),\n height: this.parseWidthHeight(\n form.querySelector(Selectors.IFRAME.elements.height).value,\n ),\n };\n }\n\n async generateIframeHtml(values) {\n const parsed = this.parseInput(values.url);\n if (!parsed) {\n return '';\n }\n\n if (values.textLinkOnly) {\n let viewUrl;\n if (parsed.isGeneric || parsed.isLtiLaunch) {\n viewUrl = parsed.rawUrl;\n } else {\n viewUrl = `${parsed.baseUrl}/view?m=${parsed.videoId}`;\n }\n\n const escapeHtml = (str) => {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n };\n\n const linkText = escapeHtml(viewUrl);\n const hrefUrl = viewUrl.replace(/\"/g, '"');\n\n return `

${linkText}

`;\n }\n\n const embedUrl = this.buildEmbedUrl(parsed, values);\n\n const context = {\n src: embedUrl,\n maxWidth: values.width || 560,\n height: values.height || 315,\n aspectRatioCSS: this.computeAspectRatioCSS(values),\n };\n\n const { html } = await Templates.renderForPromise(\n 'tiny_mediacms/iframe_embed_output',\n context,\n );\n return html;\n }\n\n async updatePreview(root, updateUrlField = false) {\n const values = this.getFormValues(root);\n const previewContainer = root.querySelector(\n Selectors.IFRAME.elements.preview,\n );\n const urlWarning = root.querySelector(\n Selectors.IFRAME.elements.urlWarning,\n );\n\n if (!values.url) {\n previewContainer.innerHTML =\n 'Enter a video URL to see preview';\n urlWarning.classList.add('d-none');\n return;\n }\n\n const parsed = this.parseInput(values.url);\n if (!parsed) {\n previewContainer.innerHTML =\n 'Invalid URL format';\n urlWarning.classList.remove('d-none');\n return;\n }\n\n urlWarning.classList.add('d-none');\n const embedUrl = this.buildEmbedUrl(parsed, values);\n\n if (updateUrlField && !parsed.isGeneric) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n const urlInput = form.querySelector(Selectors.IFRAME.elements.url);\n urlInput.value = embedUrl;\n }\n\n if (values.textLinkOnly) {\n let viewUrl;\n if (parsed.isGeneric || parsed.isLtiLaunch) {\n viewUrl = parsed.rawUrl;\n } else {\n viewUrl = `${parsed.baseUrl}/view?m=${parsed.videoId}`;\n }\n\n const escapeHtml = (str) => {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n };\n\n const linkText = escapeHtml(viewUrl);\n const hrefUrl = viewUrl.replace(/\"/g, '"');\n\n previewContainer.innerHTML = `\n
\n Text link preview:
\n ${linkText}\n
\n `;\n } else {\n const previewWidth = Math.min(values.width || 560, 400);\n const previewHeight = Math.round(previewWidth * (values.height || 315) / (values.width || 560));\n\n previewContainer.innerHTML = `\n \n \n `;\n }\n }\n\n handleInputChange(root, updateUrlField = false) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(() => {\n this.updatePreview(root, updateUrlField);\n }, 500);\n }\n\n handleWidthChange(root) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n const widthInput = form.querySelector(Selectors.IFRAME.elements.width);\n const heightInput = form.querySelector(Selectors.IFRAME.elements.height);\n const newWidth = parseInt(widthInput.value);\n if (!isNaN(newWidth) && newWidth > 0) {\n heightInput.value = Math.round(newWidth * 9 / 16);\n }\n this.handleInputChange(root);\n }\n\n handleHeightChange(root) {\n this.handleInputChange(root);\n }\n\n async handleDialogueSubmission(modal) {\n const root = modal.getRoot()[0];\n const values = this.getFormValues(root);\n\n if (!values.url) {\n return;\n }\n\n const html = await this.generateIframeHtml(values);\n if (html) {\n if (this.isUpdating && this.selectedIframe) {\n const wrapper =\n this.selectedIframe.closest(\n '.tiny-mediacms-iframe-wrapper',\n ) || this.selectedIframe.closest('.tiny-iframe-responsive');\n\n const paragraphWrapper = wrapper ? wrapper.closest('p') : this.selectedIframe.closest('p');\n\n if (paragraphWrapper) {\n paragraphWrapper.outerHTML = html;\n } else if (wrapper) {\n wrapper.outerHTML = html;\n } else {\n this.selectedIframe.outerHTML = html;\n }\n this.isUpdating = false;\n\n setTimeout(() => {\n const body = this.editor.getBody();\n const emptyPs = body.querySelectorAll('p:empty, p:blank');\n emptyPs.forEach(p => {\n if (p.innerHTML.trim() === '' || p.innerHTML === '
') {\n p.remove();\n }\n });\n }, 10);\n\n this.editor.fire('Change');\n } else {\n const node = this.editor.selection.getNode();\n if (node.nodeName === 'P' && node.innerHTML.trim() === '') {\n node.outerHTML = html;\n } else {\n this.editor.insertContent(html);\n }\n setTimeout(() => {\n const body = this.editor.getBody();\n body.querySelectorAll('p').forEach(p => {\n if (p.innerHTML.trim() === '' || p.innerHTML === '
') {\n p.remove();\n }\n });\n }, 50);\n }\n }\n }\n\n async handleRemove(modal) {\n const confirmMessage = await getString(\n 'removeiframeconfirm',\n component,\n );\n\n // eslint-disable-next-line no-alert\n if (!window.confirm(confirmMessage)) {\n return;\n }\n\n if (this.selectedIframe) {\n const wrapper =\n this.selectedIframe.closest('.tiny-mediacms-iframe-wrapper') ||\n this.selectedIframe.closest('.tiny-iframe-responsive');\n if (wrapper) {\n wrapper.remove();\n } else {\n this.selectedIframe.remove();\n }\n }\n\n this.isUpdating = false;\n modal.hide();\n }\n\n async registerEventListeners(modal) {\n await modal.getBody();\n const $root = modal.getRoot();\n const root = $root[0];\n\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n\n form.querySelector(Selectors.IFRAME.elements.url).addEventListener(\n 'input',\n () => this.handleInputChange(root),\n );\n\n [\n Selectors.IFRAME.elements.showTitle,\n Selectors.IFRAME.elements.linkTitle,\n Selectors.IFRAME.elements.showUserAvatar,\n Selectors.IFRAME.elements.startAtEnabled,\n ].forEach((selector) => {\n form.querySelector(selector).addEventListener('change', () =>\n this.handleInputChange(root, true),\n );\n });\n\n form.querySelector(Selectors.IFRAME.elements.textLinkOnly).addEventListener('change', () =>\n this.handleInputChange(root, false),\n );\n\n form.querySelector(Selectors.IFRAME.elements.startAt).addEventListener(\n 'input',\n () => this.handleInputChange(root, true),\n );\n\n form.querySelector(Selectors.IFRAME.elements.width).addEventListener(\n 'input',\n () => this.handleWidthChange(root),\n );\n form.querySelector(Selectors.IFRAME.elements.height).addEventListener(\n 'input',\n () => this.handleHeightChange(root),\n );\n\n $root.on(ModalEvents.save, () => this.handleDialogueSubmission(modal));\n $root.on(ModalEvents.hidden, () => {\n this.currentModal.destroy();\n });\n\n const removeBtn = root.querySelector(Selectors.IFRAME.actions.remove);\n if (removeBtn) {\n removeBtn.addEventListener('click', () => this.handleRemove(modal));\n }\n\n const urlInput = form.querySelector(Selectors.IFRAME.elements.url);\n if (urlInput.value) {\n this.updatePreview(root);\n }\n\n const iframeLibraryTabBtn = form.querySelector(\n Selectors.IFRAME.elements.tabIframeLibraryBtn,\n );\n if (iframeLibraryTabBtn) {\n iframeLibraryTabBtn.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n this.switchToIframeLibraryTab(root);\n\n setTimeout(() => this.handleIframeLibraryTabClick(root), 100);\n });\n iframeLibraryTabBtn.addEventListener('shown.bs.tab', () =>\n this.handleIframeLibraryTabClick(root),\n );\n const $iframeLibraryTabBtn = window.jQuery\n ? window.jQuery(iframeLibraryTabBtn)\n : null;\n if ($iframeLibraryTabBtn) {\n $iframeLibraryTabBtn.on('shown.bs.tab', () =>\n this.handleIframeLibraryTabClick(root),\n );\n }\n }\n\n const urlTabBtn = form.querySelector(\n Selectors.IFRAME.elements.tabUrlBtn,\n );\n if (urlTabBtn) {\n urlTabBtn.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n this.switchToUrlTab(root);\n });\n }\n\n const uploadMediaBtn = form.querySelector(\n Selectors.IFRAME.elements.tabUploadMediaBtn,\n );\n if (uploadMediaBtn) {\n uploadMediaBtn.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n this.switchToIframeLibraryTab(root);\n\n let uploadUrl = '';\n const ltiConfig = getLti(this.editor);\n\n if (ltiConfig && ltiConfig.contentItemUrl) {\n try {\n const urlObj = new URL(ltiConfig.contentItemUrl);\n urlObj.searchParams.set('action', 'upload');\n uploadUrl = urlObj.toString();\n } catch (err) {\n // eslint-disable-next-line no-unused-vars\n }\n }\n\n if (!uploadUrl) {\n let baseUrl = '';\n try {\n const editorData = getData(this.editor);\n if (editorData && editorData.mediacmsBaseUrl) {\n baseUrl = editorData.mediacmsBaseUrl;\n }\n } catch (err) {\n // eslint-disable-next-line no-unused-vars\n }\n\n if (!baseUrl) {\n try {\n const urlObj = new URL(this.iframeLibraryUrl);\n baseUrl = `${urlObj.protocol}//${urlObj.host}`;\n } catch (err) {\n // eslint-disable-next-line no-unused-vars\n }\n }\n\n baseUrl = baseUrl.replace(/\\/$/, '');\n uploadUrl = baseUrl ? `${baseUrl}/upload` : '';\n }\n\n if (uploadUrl) {\n const pane = form.querySelector(Selectors.IFRAME.elements.paneIframeLibrary);\n if (pane) {\n const iframeEl = pane.querySelector(Selectors.IFRAME.elements.iframeLibraryFrame);\n const placeholderEl = pane.querySelector(Selectors.IFRAME.elements.iframeLibraryPlaceholder);\n const loadingEl = pane.querySelector(Selectors.IFRAME.elements.iframeLibraryLoading);\n\n if (placeholderEl) {\n placeholderEl.classList.add('d-none');\n }\n if (loadingEl) {\n loadingEl.classList.remove('d-none');\n }\n if (iframeEl) {\n iframeEl.classList.add('d-none');\n\n const loadHandler = () => {\n this.handleIframeLibraryLoad(root);\n iframeEl.removeEventListener('load', loadHandler);\n };\n iframeEl.addEventListener('load', loadHandler);\n iframeEl.src = uploadUrl;\n }\n }\n }\n });\n }\n\n this.registerIframeLibraryEventListeners(root);\n\n if (this.isUpdating) {\n setTimeout(() => this.updatePreview(root), 100);\n } else {\n setTimeout(() => this.handleIframeLibraryTabClick(root), 100);\n }\n }\n\n switchToUrlTab(root) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n\n const urlTabBtn = form.querySelector(\n Selectors.IFRAME.elements.tabUrlBtn,\n );\n const urlTabItem = form.querySelector('.tiny_iframecms_tab_url_item');\n const iframeLibraryTabBtn = form.querySelector(\n Selectors.IFRAME.elements.tabIframeLibraryBtn,\n );\n\n const urlPane = form.querySelector(Selectors.IFRAME.elements.paneUrl);\n const iframeLibraryPane = form.querySelector(\n Selectors.IFRAME.elements.paneIframeLibrary,\n );\n\n if (urlTabItem) {\n urlTabItem.style.display = '';\n }\n\n if (urlTabBtn) {\n urlTabBtn.classList.add('active');\n urlTabBtn.setAttribute('aria-selected', 'true');\n }\n if (iframeLibraryTabBtn) {\n iframeLibraryTabBtn.classList.remove('active');\n iframeLibraryTabBtn.setAttribute('aria-selected', 'false');\n }\n\n if (urlPane) {\n urlPane.classList.add('show', 'active');\n }\n if (iframeLibraryPane) {\n iframeLibraryPane.classList.remove('show', 'active');\n }\n }\n\n switchToIframeLibraryTab(root) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n\n const urlTabBtn = form.querySelector(\n Selectors.IFRAME.elements.tabUrlBtn,\n );\n const urlTabItem = form.querySelector('.tiny_iframecms_tab_url_item');\n const iframeLibraryTabBtn = form.querySelector(\n Selectors.IFRAME.elements.tabIframeLibraryBtn,\n );\n\n const urlPane = form.querySelector(Selectors.IFRAME.elements.paneUrl);\n const iframeLibraryPane = form.querySelector(\n Selectors.IFRAME.elements.paneIframeLibrary,\n );\n\n if (urlTabItem) {\n urlTabItem.style.display = 'none';\n }\n\n if (urlTabBtn) {\n urlTabBtn.classList.remove('active');\n urlTabBtn.setAttribute('aria-selected', 'false');\n }\n if (iframeLibraryTabBtn) {\n iframeLibraryTabBtn.classList.add('active');\n iframeLibraryTabBtn.setAttribute('aria-selected', 'true');\n }\n\n if (urlPane) {\n urlPane.classList.remove('show', 'active');\n }\n if (iframeLibraryPane) {\n iframeLibraryPane.classList.add('show', 'active');\n }\n }\n\n registerIframeLibraryEventListeners(root) {\n window.addEventListener('message', (event) => {\n this.handleIframeLibraryMessage(root, event);\n });\n }\n\n handleIframeLibraryTabClick(root) {\n this.loadIframeLibrary(root);\n }\n\n loadIframeLibrary(root) {\n const ltiConfig = getLti(this.editor);\n if (ltiConfig?.contentItemUrl) {\n this.loadIframeLibraryViaLti(root);\n } else {\n this.loadIframeLibraryStatic(root);\n }\n }\n\n loadIframeLibraryViaLti(root) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n const pane = form.querySelector(\n Selectors.IFRAME.elements.paneIframeLibrary,\n );\n\n if (!pane) {\n return;\n }\n\n const placeholderEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryPlaceholder,\n );\n const loadingEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryLoading,\n );\n const iframeEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryFrame,\n );\n\n if (!iframeEl) {\n return;\n }\n\n if (placeholderEl) {\n placeholderEl.classList.add('d-none');\n }\n if (loadingEl) {\n loadingEl.classList.remove('d-none');\n }\n iframeEl.classList.add('d-none');\n\n const loadHandler = () => {\n this.handleIframeLibraryLoad(root);\n };\n iframeEl.addEventListener('load', loadHandler);\n\n const ltiConfig = getLti(this.editor);\n iframeEl.src = ltiConfig.contentItemUrl;\n }\n\n loadIframeLibraryStatic(root) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n const pane = form.querySelector(\n Selectors.IFRAME.elements.paneIframeLibrary,\n );\n\n if (!pane) {\n return;\n }\n\n const placeholderEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryPlaceholder,\n );\n const loadingEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryLoading,\n );\n const iframeEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryFrame,\n );\n\n if (!iframeEl) {\n return;\n }\n\n if (placeholderEl) {\n placeholderEl.classList.add('d-none');\n }\n if (loadingEl) {\n loadingEl.classList.remove('d-none');\n }\n iframeEl.classList.add('d-none');\n\n const loadHandler = () => {\n if (iframeEl.src === this.iframeLibraryUrl) {\n this.handleIframeLibraryLoad(root);\n iframeEl.removeEventListener('load', loadHandler);\n }\n };\n iframeEl.addEventListener('load', loadHandler);\n\n iframeEl.src = this.iframeLibraryUrl;\n }\n\n handleIframeLibraryLoad(root) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n const pane = form.querySelector(\n Selectors.IFRAME.elements.paneIframeLibrary,\n );\n\n if (!pane) {\n return;\n }\n\n const placeholderEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryPlaceholder,\n );\n const loadingEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryLoading,\n );\n const iframeEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryFrame,\n );\n\n if (placeholderEl) {\n placeholderEl.classList.add('d-none');\n }\n if (loadingEl) {\n loadingEl.classList.add('d-none');\n }\n if (iframeEl) {\n iframeEl.classList.remove('d-none');\n }\n }\n\n handleIframeLibraryMessage(root, event) {\n const data = event.data;\n\n if (!data) {\n return;\n }\n\n if (data.type === 'videoSelected' && data.embedUrl) {\n this.selectIframeLibraryVideo(root, data.embedUrl, data.videoId);\n return;\n }\n\n if (\n data.type === 'ltiDeepLinkingResponse' ||\n data.messageType === 'LtiDeepLinkingResponse'\n ) {\n const contentItems = data.content_items || data.contentItems || [];\n if (contentItems.length > 0) {\n const item = contentItems[0];\n const embedUrl =\n item.url || item.embed_url || item.embedUrl || '';\n const videoId = item.id || item.mediaId || '';\n if (embedUrl) {\n this.selectIframeLibraryVideo(root, embedUrl, videoId);\n }\n }\n return;\n }\n\n if (data.action === 'selectMedia' || data.action === 'mediaSelected') {\n const embedUrl = data.embedUrl || data.url || '';\n if (embedUrl) {\n this.selectIframeLibraryVideo(root, embedUrl);\n }\n return;\n }\n }\n\n selectIframeLibraryVideo(root, embedUrl) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n\n const urlInput = form.querySelector(Selectors.IFRAME.elements.url);\n urlInput.value = embedUrl;\n\n const configureTabItem = root.querySelector('.tiny_iframecms_tab_url_item');\n if (configureTabItem) {\n configureTabItem.style.display = '';\n }\n\n this.switchToUrlTab(root);\n this.updatePreview(root);\n }\n}\n"],"names":["constructor","editor","parseInput","input","trim","iframeMatch","match","this","parseEmbedUrl","startsWith","parseVideoUrl","url","urlObj","URL","baseUrl","protocol","host","pathname","searchParams","has","videoId","get","isEmbed","tParam","widthParam","heightParam","showTitle","linkTitle","showUserAvatar","width","parseInt","height","startAt","secondsToTimeString","includes","rawUrl","isLtiLaunch","isGeneric","e","seconds","mins","Math","floor","secs","toString","padStart","timeStringToSeconds","timeStr","parts","split","isNaN","parseWidthHeight","value","parsed","computeAspectRatioCSS","values","w","h","buildEmbedUrl","options","token","courseid","search","set","startAtEnabled","data","editorData","autoConvertOptions","getDefault","key","fallback","_this","isUpdating","undefined","elementid","getElement","id","isupdating","textLinkOnly","selectedIframe","getSelectedIframe","getCurrentIframeData","currentModal","IframeModal","create","title","component","templateContext","getTemplateContext","registerEventListeners","node","selection","getNode","nodeName","toLowerCase","getAttribute","iframe","querySelector","wrapper","closest","textLink","href","responsive","src","style","maxWidthMatch","aspectRatioMatch","maxWidth","rw","parseFloat","rh","round","getFormValues","root","form","Selectors","IFRAME","elements","checked","viewUrl","linkText","str","div","document","createElement","textContent","innerHTML","escapeHtml","hrefUrl","replace","context","aspectRatioCSS","html","Templates","renderForPromise","updateUrlField","previewContainer","preview","urlWarning","classList","add","remove","embedUrl","previewWidth","min","previewHeight","handleInputChange","clearTimeout","debounceTimer","setTimeout","updatePreview","handleWidthChange","widthInput","heightInput","newWidth","handleHeightChange","modal","getRoot","generateIframeHtml","paragraphWrapper","outerHTML","getBody","querySelectorAll","forEach","p","fire","insertContent","confirmMessage","window","confirm","hide","$root","addEventListener","selector","on","ModalEvents","save","handleDialogueSubmission","hidden","destroy","removeBtn","actions","handleRemove","iframeLibraryTabBtn","tabIframeLibraryBtn","preventDefault","stopPropagation","switchToIframeLibraryTab","handleIframeLibraryTabClick","$iframeLibraryTabBtn","jQuery","urlTabBtn","tabUrlBtn","switchToUrlTab","uploadMediaBtn","tabUploadMediaBtn","uploadUrl","ltiConfig","contentItemUrl","err","mediacmsBaseUrl","iframeLibraryUrl","pane","paneIframeLibrary","iframeEl","iframeLibraryFrame","placeholderEl","iframeLibraryPlaceholder","loadingEl","iframeLibraryLoading","loadHandler","handleIframeLibraryLoad","removeEventListener","registerIframeLibraryEventListeners","urlTabItem","urlPane","paneUrl","iframeLibraryPane","display","setAttribute","event","handleIframeLibraryMessage","loadIframeLibrary","loadIframeLibraryViaLti","loadIframeLibraryStatic","type","selectIframeLibraryVideo","messageType","action","contentItems","content_items","length","item","embed_url","mediaId","configureTabItem"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"iframeembed.min.js","sources":["../src/iframeembed.js"],"sourcesContent":["import Templates from 'core/templates';\nimport { getString } from 'core/str';\nimport * as ModalEvents from 'core/modal_events';\nimport { component } from './common';\nimport IframeModal from './iframemodal';\nimport Selectors from './selectors';\nimport { getLti, getData } from './options';\n\nexport default class IframeEmbed {\n editor = null;\n currentModal = null;\n isUpdating = false;\n selectedIframe = null;\n debounceTimer = null;\n iframeLibraryUrl =\n 'https://temp.web357.com/mediacms/deic-mediacms-embed-videos.html';\n\n constructor(editor) {\n this.editor = editor;\n }\n\n parseInput(input) {\n if (!input || !input.trim()) {\n return null;\n }\n\n input = input.trim();\n\n const iframeMatch = input.match(\n /]*src=[\"']([^\"']+)[\"'][^>]*>/i,\n );\n if (iframeMatch) {\n return this.parseEmbedUrl(iframeMatch[1]);\n }\n\n if (input.startsWith('http://') || input.startsWith('https://')) {\n return this.parseVideoUrl(input);\n }\n\n return null;\n }\n\n parseVideoUrl(url) {\n try {\n const urlObj = new URL(url);\n const baseUrl = `${urlObj.protocol}//${urlObj.host}`;\n\n if (urlObj.pathname === '/view' && urlObj.searchParams.has('m')) {\n return {\n baseUrl: baseUrl,\n videoId: urlObj.searchParams.get('m'),\n isEmbed: false,\n };\n }\n\n if (urlObj.pathname === '/embed' && urlObj.searchParams.has('m')) {\n const tParam = urlObj.searchParams.get('t');\n const widthParam = urlObj.searchParams.get('width');\n const heightParam = urlObj.searchParams.get('height');\n return {\n baseUrl: baseUrl,\n videoId: urlObj.searchParams.get('m'),\n isEmbed: true,\n showTitle: urlObj.searchParams.get('showTitle') === '1',\n linkTitle: urlObj.searchParams.get('linkTitle') === '1',\n showUserAvatar:\n urlObj.searchParams.get('showUserAvatar') === '1',\n width: widthParam ? parseInt(widthParam) : null,\n height: heightParam ? parseInt(heightParam) : null,\n startAt: tParam\n ? this.secondsToTimeString(parseInt(tParam))\n : null,\n };\n }\n\n if (urlObj.pathname.includes('/filter/mediacms/launch.php') && urlObj.searchParams.has('token')) {\n const tParam = urlObj.searchParams.get('t');\n const widthParam = urlObj.searchParams.get('width');\n const heightParam = urlObj.searchParams.get('height');\n\n return {\n baseUrl: baseUrl,\n videoId: urlObj.searchParams.get('token'),\n rawUrl: url,\n isLtiLaunch: true,\n showTitle: urlObj.searchParams.get('showTitle') === '1',\n linkTitle: urlObj.searchParams.get('linkTitle') === '1',\n showUserAvatar: urlObj.searchParams.get('showUserAvatar') === '1',\n width: widthParam ? parseInt(widthParam) : null,\n height: heightParam ? parseInt(heightParam) : null,\n startAt: tParam ? this.secondsToTimeString(parseInt(tParam)) : null,\n };\n }\n\n return {\n baseUrl: baseUrl,\n rawUrl: url,\n isGeneric: true,\n };\n } catch (e) {\n return null;\n }\n }\n\n parseEmbedUrl(url) {\n return this.parseVideoUrl(url);\n }\n\n secondsToTimeString(seconds) {\n const mins = Math.floor(seconds / 60);\n const secs = seconds % 60;\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n }\n\n timeStringToSeconds(timeStr) {\n if (!timeStr || !timeStr.trim()) {\n return null;\n }\n timeStr = timeStr.trim();\n\n if (timeStr.includes(':')) {\n const parts = timeStr.split(':');\n const mins = parseInt(parts[0]) || 0;\n const secs = parseInt(parts[1]) || 0;\n return mins * 60 + secs;\n }\n\n const secs = parseInt(timeStr);\n return isNaN(secs) ? null : secs;\n }\n\n parseWidthHeight(value) {\n if (!value) {\n return null;\n }\n const parsed = parseInt(value.trim());\n return isNaN(parsed) ? null : parsed;\n }\n\n computeAspectRatioCSS(values) {\n const w = values.width || 560;\n const h = values.height || 315;\n return `${w} / ${h}`;\n }\n\n buildEmbedUrl(parsed, options) {\n if (parsed.isGeneric) {\n return parsed.rawUrl;\n }\n\n let url;\n if (parsed.isLtiLaunch) {\n url = new URL(parsed.rawUrl);\n const token = url.searchParams.get('token');\n const courseid = url.searchParams.get('courseid');\n url.search = '';\n url.searchParams.set('token', token);\n if (courseid) {\n url.searchParams.set('courseid', courseid);\n }\n } else {\n url = new URL(`${parsed.baseUrl}/embed`);\n url.searchParams.set('m', parsed.videoId);\n }\n\n url.searchParams.set('showTitle', options.showTitle ? '1' : '0');\n url.searchParams.set(\n 'showUserAvatar',\n options.showUserAvatar ? '1' : '0',\n );\n url.searchParams.set('linkTitle', options.linkTitle ? '1' : '0');\n\n if (options.startAtEnabled && options.startAt) {\n const seconds = this.timeStringToSeconds(options.startAt);\n if (seconds !== null && seconds > 0) {\n url.searchParams.set('t', seconds.toString());\n }\n }\n\n if (options.width) {\n url.searchParams.set('width', options.width);\n }\n if (options.height) {\n url.searchParams.set('height', options.height);\n }\n\n return url.toString();\n }\n\n async getTemplateContext(data = {}) {\n const editorData = getData(this.editor);\n const autoConvertOptions = editorData?.autoConvertOptions || {};\n\n const getDefault = (key, fallback = true) => {\n if (this.isUpdating && data[key] !== undefined) {\n return data[key];\n }\n return autoConvertOptions[key] !== undefined\n ? autoConvertOptions[key]\n : fallback;\n };\n\n const width = (this.isUpdating && data.width) ? data.width : 560;\n const height = (this.isUpdating && data.height) ? data.height : 315;\n\n return {\n elementid: this.editor.getElement().id,\n isupdating: this.isUpdating,\n url: data.url || '',\n showTitle: getDefault('showTitle'),\n linkTitle: getDefault('linkTitle'),\n showUserAvatar: getDefault('showUserAvatar'),\n textLinkOnly: data.textLinkOnly || false,\n startAtEnabled: data.startAtEnabled || false,\n startAt: data.startAt || '0:00',\n width,\n height,\n };\n }\n\n async displayDialogue() {\n this.selectedIframe = this.getSelectedIframe();\n const data = this.getCurrentIframeData();\n this.isUpdating = data !== null;\n\n this.currentModal = await IframeModal.create({\n title: getString('iframemodaltitle', component),\n templateContext: await this.getTemplateContext(data || {}),\n });\n\n await this.registerEventListeners(this.currentModal);\n }\n\n getSelectedIframe() {\n const node = this.editor.selection.getNode();\n\n if (node.nodeName.toLowerCase() === 'a' && node.getAttribute('data-mediacms-textlink') === 'true') {\n return node;\n }\n\n if (node.nodeName.toLowerCase() === 'iframe') {\n return node;\n }\n\n const iframe = node.querySelector('iframe');\n if (iframe) {\n return iframe;\n }\n\n const wrapper =\n node.closest('.tiny-mediacms-iframe-wrapper') ||\n node.closest('.tiny-iframe-responsive');\n if (wrapper) {\n return wrapper.querySelector('iframe');\n }\n\n const textLink = node.closest('a[data-mediacms-textlink=\"true\"]');\n if (textLink) {\n return textLink;\n }\n\n return null;\n }\n\n getCurrentIframeData() {\n if (!this.selectedIframe) {\n return null;\n }\n\n if (this.selectedIframe.nodeName.toLowerCase() === 'a' &&\n this.selectedIframe.getAttribute('data-mediacms-textlink') === 'true') {\n const href = this.selectedIframe.getAttribute('href');\n const parsed = this.parseInput(href);\n\n return {\n url: href,\n width: parsed?.width || 560,\n height: parsed?.height || 315,\n showTitle: parsed?.showTitle ?? true,\n linkTitle: parsed?.linkTitle ?? true,\n showUserAvatar: parsed?.showUserAvatar ?? true,\n responsive: true,\n textLinkOnly: true,\n startAtEnabled: parsed?.startAt !== null,\n startAt: parsed?.startAt || '0:00',\n };\n }\n\n const src = this.selectedIframe.getAttribute('src');\n const parsed = this.parseInput(src);\n\n // Parse responsive dimensions from inline style\n const style = this.selectedIframe.getAttribute('style') || '';\n const maxWidthMatch = style.match(/max-width:\\s*(\\d+(?:\\.\\d+)?)px/);\n const aspectRatioMatch = style.match(/aspect-ratio:\\s*(\\d+(?:\\.\\d+)?)\\s*\\/\\s*(\\d+(?:\\.\\d+)?)/);\n\n // Fall back to wrapper's max-width for content saved with the new template\n // where max-width lives on the wrapper div rather than the iframe style.\n let maxWidth = maxWidthMatch ? parseInt(maxWidthMatch[1]) : null;\n if (!maxWidth) {\n const wrapper = this.selectedIframe.closest('.tiny-mediacms-iframe-wrapper');\n const wrapperStyle = wrapper ? (wrapper.getAttribute('style') || '') : '';\n const wrapperMatch = wrapperStyle.match(/max-width:\\s*(\\d+(?:\\.\\d+)?)px/);\n maxWidth = wrapperMatch ? parseInt(wrapperMatch[1]) : 560;\n }\n let height = 315;\n\n if (aspectRatioMatch) {\n const rw = parseFloat(aspectRatioMatch[1]);\n const rh = parseFloat(aspectRatioMatch[2]);\n if (rw > 0) {\n height = Math.round(maxWidth * rh / rw);\n }\n }\n\n return {\n url: src,\n width: maxWidth,\n height,\n showTitle: parsed?.showTitle ?? true,\n linkTitle: parsed?.linkTitle ?? true,\n showUserAvatar: parsed?.showUserAvatar ?? true,\n startAtEnabled: !!(parsed?.startAt),\n startAt: parsed?.startAt || '0:00',\n };\n }\n\n getFormValues(root) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n\n return {\n url: form.querySelector(Selectors.IFRAME.elements.url).value.trim(),\n showTitle: form.querySelector(Selectors.IFRAME.elements.showTitle)\n .checked,\n linkTitle: form.querySelector(Selectors.IFRAME.elements.linkTitle)\n .checked,\n showUserAvatar: form.querySelector(\n Selectors.IFRAME.elements.showUserAvatar,\n ).checked,\n textLinkOnly: form.querySelector(Selectors.IFRAME.elements.textLinkOnly)\n .checked,\n startAtEnabled: form.querySelector(\n Selectors.IFRAME.elements.startAtEnabled,\n ).checked,\n startAt: form\n .querySelector(Selectors.IFRAME.elements.startAt)\n .value.trim(),\n width: this.parseWidthHeight(\n form.querySelector(Selectors.IFRAME.elements.width).value,\n ),\n height: this.parseWidthHeight(\n form.querySelector(Selectors.IFRAME.elements.height).value,\n ),\n };\n }\n\n async generateIframeHtml(values) {\n const parsed = this.parseInput(values.url);\n if (!parsed) {\n return '';\n }\n\n if (values.textLinkOnly) {\n let viewUrl;\n if (parsed.isGeneric || parsed.isLtiLaunch) {\n viewUrl = parsed.rawUrl;\n } else {\n viewUrl = `${parsed.baseUrl}/view?m=${parsed.videoId}`;\n }\n\n const escapeHtml = (str) => {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n };\n\n const linkText = escapeHtml(viewUrl);\n const hrefUrl = viewUrl.replace(/\"/g, '"');\n\n return `

${linkText}

`;\n }\n\n const embedUrl = this.buildEmbedUrl(parsed, values);\n\n const context = {\n src: embedUrl,\n maxWidth: values.width || 560,\n height: values.height || 315,\n aspectRatioCSS: this.computeAspectRatioCSS(values),\n };\n\n const { html } = await Templates.renderForPromise(\n 'tiny_mediacms/iframe_embed_output',\n context,\n );\n return html;\n }\n\n async updatePreview(root, updateUrlField = false) {\n const values = this.getFormValues(root);\n const previewContainer = root.querySelector(\n Selectors.IFRAME.elements.preview,\n );\n const urlWarning = root.querySelector(\n Selectors.IFRAME.elements.urlWarning,\n );\n\n if (!values.url) {\n previewContainer.innerHTML =\n 'Enter a video URL to see preview';\n urlWarning.classList.add('d-none');\n return;\n }\n\n const parsed = this.parseInput(values.url);\n if (!parsed) {\n previewContainer.innerHTML =\n 'Invalid URL format';\n urlWarning.classList.remove('d-none');\n return;\n }\n\n urlWarning.classList.add('d-none');\n const embedUrl = this.buildEmbedUrl(parsed, values);\n\n if (updateUrlField && !parsed.isGeneric) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n const urlInput = form.querySelector(Selectors.IFRAME.elements.url);\n urlInput.value = embedUrl;\n }\n\n if (values.textLinkOnly) {\n let viewUrl;\n if (parsed.isGeneric || parsed.isLtiLaunch) {\n viewUrl = parsed.rawUrl;\n } else {\n viewUrl = `${parsed.baseUrl}/view?m=${parsed.videoId}`;\n }\n\n const escapeHtml = (str) => {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n };\n\n const linkText = escapeHtml(viewUrl);\n const hrefUrl = viewUrl.replace(/\"/g, '"');\n\n previewContainer.innerHTML = `\n
\n Text link preview:
\n ${linkText}\n
\n `;\n } else {\n const previewWidth = Math.min(values.width || 560, 400);\n const previewHeight = Math.round(previewWidth * (values.height || 315) / (values.width || 560));\n\n previewContainer.innerHTML = `\n \n \n `;\n }\n }\n\n handleInputChange(root, updateUrlField = false) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(() => {\n this.updatePreview(root, updateUrlField);\n }, 500);\n }\n\n handleWidthChange(root) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n const widthInput = form.querySelector(Selectors.IFRAME.elements.width);\n const heightInput = form.querySelector(Selectors.IFRAME.elements.height);\n const newWidth = parseInt(widthInput.value);\n if (!isNaN(newWidth) && newWidth > 0) {\n heightInput.value = Math.round(newWidth * 9 / 16);\n }\n this.handleInputChange(root);\n }\n\n handleHeightChange(root) {\n this.handleInputChange(root);\n }\n\n async handleDialogueSubmission(modal) {\n const root = modal.getRoot()[0];\n const values = this.getFormValues(root);\n\n if (!values.url) {\n return;\n }\n\n const html = await this.generateIframeHtml(values);\n if (html) {\n if (this.isUpdating && this.selectedIframe) {\n const wrapper =\n this.selectedIframe.closest(\n '.tiny-mediacms-iframe-wrapper',\n ) || this.selectedIframe.closest('.tiny-iframe-responsive');\n\n const paragraphWrapper = wrapper ? wrapper.closest('p') : this.selectedIframe.closest('p');\n\n if (paragraphWrapper) {\n paragraphWrapper.outerHTML = html;\n } else if (wrapper) {\n wrapper.outerHTML = html;\n } else {\n this.selectedIframe.outerHTML = html;\n }\n this.isUpdating = false;\n\n setTimeout(() => {\n const body = this.editor.getBody();\n const emptyPs = body.querySelectorAll('p:empty, p:blank');\n emptyPs.forEach(p => {\n if (p.innerHTML.trim() === '' || p.innerHTML === '
') {\n p.remove();\n }\n });\n }, 10);\n\n this.editor.fire('Change');\n } else {\n const node = this.editor.selection.getNode();\n if (node.nodeName === 'P' && node.innerHTML.trim() === '') {\n node.outerHTML = html;\n } else {\n this.editor.insertContent(html);\n }\n setTimeout(() => {\n const body = this.editor.getBody();\n body.querySelectorAll('p').forEach(p => {\n if (p.innerHTML.trim() === '' || p.innerHTML === '
') {\n p.remove();\n }\n });\n }, 50);\n }\n }\n }\n\n async handleRemove(modal) {\n const confirmMessage = await getString(\n 'removeiframeconfirm',\n component,\n );\n\n // eslint-disable-next-line no-alert\n if (!window.confirm(confirmMessage)) {\n return;\n }\n\n if (this.selectedIframe) {\n const wrapper =\n this.selectedIframe.closest('.tiny-mediacms-iframe-wrapper') ||\n this.selectedIframe.closest('.tiny-iframe-responsive');\n if (wrapper) {\n wrapper.remove();\n } else {\n this.selectedIframe.remove();\n }\n }\n\n this.isUpdating = false;\n modal.hide();\n }\n\n async registerEventListeners(modal) {\n await modal.getBody();\n const $root = modal.getRoot();\n const root = $root[0];\n\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n\n form.querySelector(Selectors.IFRAME.elements.url).addEventListener(\n 'input',\n () => this.handleInputChange(root),\n );\n\n [\n Selectors.IFRAME.elements.showTitle,\n Selectors.IFRAME.elements.linkTitle,\n Selectors.IFRAME.elements.showUserAvatar,\n Selectors.IFRAME.elements.startAtEnabled,\n ].forEach((selector) => {\n form.querySelector(selector).addEventListener('change', () =>\n this.handleInputChange(root, true),\n );\n });\n\n form.querySelector(Selectors.IFRAME.elements.textLinkOnly).addEventListener('change', () =>\n this.handleInputChange(root, false),\n );\n\n form.querySelector(Selectors.IFRAME.elements.startAt).addEventListener(\n 'input',\n () => this.handleInputChange(root, true),\n );\n\n form.querySelector(Selectors.IFRAME.elements.width).addEventListener(\n 'input',\n () => this.handleWidthChange(root),\n );\n form.querySelector(Selectors.IFRAME.elements.height).addEventListener(\n 'input',\n () => this.handleHeightChange(root),\n );\n\n $root.on(ModalEvents.save, () => this.handleDialogueSubmission(modal));\n $root.on(ModalEvents.hidden, () => {\n this.currentModal.destroy();\n });\n\n const removeBtn = root.querySelector(Selectors.IFRAME.actions.remove);\n if (removeBtn) {\n removeBtn.addEventListener('click', () => this.handleRemove(modal));\n }\n\n const urlInput = form.querySelector(Selectors.IFRAME.elements.url);\n if (urlInput.value) {\n this.updatePreview(root);\n }\n\n const iframeLibraryTabBtn = form.querySelector(\n Selectors.IFRAME.elements.tabIframeLibraryBtn,\n );\n if (iframeLibraryTabBtn) {\n iframeLibraryTabBtn.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n this.switchToIframeLibraryTab(root);\n\n setTimeout(() => this.handleIframeLibraryTabClick(root), 100);\n });\n iframeLibraryTabBtn.addEventListener('shown.bs.tab', () =>\n this.handleIframeLibraryTabClick(root),\n );\n const $iframeLibraryTabBtn = window.jQuery\n ? window.jQuery(iframeLibraryTabBtn)\n : null;\n if ($iframeLibraryTabBtn) {\n $iframeLibraryTabBtn.on('shown.bs.tab', () =>\n this.handleIframeLibraryTabClick(root),\n );\n }\n }\n\n const urlTabBtn = form.querySelector(\n Selectors.IFRAME.elements.tabUrlBtn,\n );\n if (urlTabBtn) {\n urlTabBtn.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n this.switchToUrlTab(root);\n });\n }\n\n const uploadMediaBtn = form.querySelector(\n Selectors.IFRAME.elements.tabUploadMediaBtn,\n );\n if (uploadMediaBtn) {\n uploadMediaBtn.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n this.switchToIframeLibraryTab(root);\n\n let uploadUrl = '';\n const ltiConfig = getLti(this.editor);\n\n if (ltiConfig && ltiConfig.contentItemUrl) {\n try {\n const urlObj = new URL(ltiConfig.contentItemUrl);\n urlObj.searchParams.set('action', 'upload');\n uploadUrl = urlObj.toString();\n } catch (err) {\n // eslint-disable-next-line no-unused-vars\n }\n }\n\n if (!uploadUrl) {\n let baseUrl = '';\n try {\n const editorData = getData(this.editor);\n if (editorData && editorData.mediacmsBaseUrl) {\n baseUrl = editorData.mediacmsBaseUrl;\n }\n } catch (err) {\n // eslint-disable-next-line no-unused-vars\n }\n\n if (!baseUrl) {\n try {\n const urlObj = new URL(this.iframeLibraryUrl);\n baseUrl = `${urlObj.protocol}//${urlObj.host}`;\n } catch (err) {\n // eslint-disable-next-line no-unused-vars\n }\n }\n\n baseUrl = baseUrl.replace(/\\/$/, '');\n uploadUrl = baseUrl ? `${baseUrl}/upload` : '';\n }\n\n if (uploadUrl) {\n const pane = form.querySelector(Selectors.IFRAME.elements.paneIframeLibrary);\n if (pane) {\n const iframeEl = pane.querySelector(Selectors.IFRAME.elements.iframeLibraryFrame);\n const placeholderEl = pane.querySelector(Selectors.IFRAME.elements.iframeLibraryPlaceholder);\n const loadingEl = pane.querySelector(Selectors.IFRAME.elements.iframeLibraryLoading);\n\n if (placeholderEl) {\n placeholderEl.classList.add('d-none');\n }\n if (loadingEl) {\n loadingEl.classList.remove('d-none');\n }\n if (iframeEl) {\n iframeEl.classList.add('d-none');\n\n const loadHandler = () => {\n this.handleIframeLibraryLoad(root);\n iframeEl.removeEventListener('load', loadHandler);\n };\n iframeEl.addEventListener('load', loadHandler);\n iframeEl.src = uploadUrl;\n }\n }\n }\n });\n }\n\n this.registerIframeLibraryEventListeners(root);\n\n if (this.isUpdating) {\n setTimeout(() => this.updatePreview(root), 100);\n } else {\n setTimeout(() => this.handleIframeLibraryTabClick(root), 100);\n }\n }\n\n switchToUrlTab(root) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n\n const urlTabBtn = form.querySelector(\n Selectors.IFRAME.elements.tabUrlBtn,\n );\n const urlTabItem = form.querySelector('.tiny_iframecms_tab_url_item');\n const iframeLibraryTabBtn = form.querySelector(\n Selectors.IFRAME.elements.tabIframeLibraryBtn,\n );\n\n const urlPane = form.querySelector(Selectors.IFRAME.elements.paneUrl);\n const iframeLibraryPane = form.querySelector(\n Selectors.IFRAME.elements.paneIframeLibrary,\n );\n\n if (urlTabItem) {\n urlTabItem.style.display = '';\n }\n\n if (urlTabBtn) {\n urlTabBtn.classList.add('active');\n urlTabBtn.setAttribute('aria-selected', 'true');\n }\n if (iframeLibraryTabBtn) {\n iframeLibraryTabBtn.classList.remove('active');\n iframeLibraryTabBtn.setAttribute('aria-selected', 'false');\n }\n\n if (urlPane) {\n urlPane.classList.add('show', 'active');\n }\n if (iframeLibraryPane) {\n iframeLibraryPane.classList.remove('show', 'active');\n }\n }\n\n switchToIframeLibraryTab(root) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n\n const urlTabBtn = form.querySelector(\n Selectors.IFRAME.elements.tabUrlBtn,\n );\n const urlTabItem = form.querySelector('.tiny_iframecms_tab_url_item');\n const iframeLibraryTabBtn = form.querySelector(\n Selectors.IFRAME.elements.tabIframeLibraryBtn,\n );\n\n const urlPane = form.querySelector(Selectors.IFRAME.elements.paneUrl);\n const iframeLibraryPane = form.querySelector(\n Selectors.IFRAME.elements.paneIframeLibrary,\n );\n\n if (urlTabItem) {\n urlTabItem.style.display = 'none';\n }\n\n if (urlTabBtn) {\n urlTabBtn.classList.remove('active');\n urlTabBtn.setAttribute('aria-selected', 'false');\n }\n if (iframeLibraryTabBtn) {\n iframeLibraryTabBtn.classList.add('active');\n iframeLibraryTabBtn.setAttribute('aria-selected', 'true');\n }\n\n if (urlPane) {\n urlPane.classList.remove('show', 'active');\n }\n if (iframeLibraryPane) {\n iframeLibraryPane.classList.add('show', 'active');\n }\n }\n\n registerIframeLibraryEventListeners(root) {\n window.addEventListener('message', (event) => {\n this.handleIframeLibraryMessage(root, event);\n });\n }\n\n handleIframeLibraryTabClick(root) {\n this.loadIframeLibrary(root);\n }\n\n loadIframeLibrary(root) {\n const ltiConfig = getLti(this.editor);\n if (ltiConfig?.contentItemUrl) {\n this.loadIframeLibraryViaLti(root);\n } else {\n this.loadIframeLibraryStatic(root);\n }\n }\n\n loadIframeLibraryViaLti(root) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n const pane = form.querySelector(\n Selectors.IFRAME.elements.paneIframeLibrary,\n );\n\n if (!pane) {\n return;\n }\n\n const placeholderEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryPlaceholder,\n );\n const loadingEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryLoading,\n );\n const iframeEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryFrame,\n );\n\n if (!iframeEl) {\n return;\n }\n\n if (placeholderEl) {\n placeholderEl.classList.add('d-none');\n }\n if (loadingEl) {\n loadingEl.classList.remove('d-none');\n }\n iframeEl.classList.add('d-none');\n\n const loadHandler = () => {\n this.handleIframeLibraryLoad(root);\n };\n iframeEl.addEventListener('load', loadHandler);\n\n const ltiConfig = getLti(this.editor);\n iframeEl.src = ltiConfig.contentItemUrl;\n }\n\n loadIframeLibraryStatic(root) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n const pane = form.querySelector(\n Selectors.IFRAME.elements.paneIframeLibrary,\n );\n\n if (!pane) {\n return;\n }\n\n const placeholderEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryPlaceholder,\n );\n const loadingEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryLoading,\n );\n const iframeEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryFrame,\n );\n\n if (!iframeEl) {\n return;\n }\n\n if (placeholderEl) {\n placeholderEl.classList.add('d-none');\n }\n if (loadingEl) {\n loadingEl.classList.remove('d-none');\n }\n iframeEl.classList.add('d-none');\n\n const loadHandler = () => {\n if (iframeEl.src === this.iframeLibraryUrl) {\n this.handleIframeLibraryLoad(root);\n iframeEl.removeEventListener('load', loadHandler);\n }\n };\n iframeEl.addEventListener('load', loadHandler);\n\n iframeEl.src = this.iframeLibraryUrl;\n }\n\n handleIframeLibraryLoad(root) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n const pane = form.querySelector(\n Selectors.IFRAME.elements.paneIframeLibrary,\n );\n\n if (!pane) {\n return;\n }\n\n const placeholderEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryPlaceholder,\n );\n const loadingEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryLoading,\n );\n const iframeEl = pane.querySelector(\n Selectors.IFRAME.elements.iframeLibraryFrame,\n );\n\n if (placeholderEl) {\n placeholderEl.classList.add('d-none');\n }\n if (loadingEl) {\n loadingEl.classList.add('d-none');\n }\n if (iframeEl) {\n iframeEl.classList.remove('d-none');\n }\n }\n\n handleIframeLibraryMessage(root, event) {\n const data = event.data;\n\n if (!data) {\n return;\n }\n\n if (data.type === 'videoSelected' && data.embedUrl) {\n this.selectIframeLibraryVideo(root, data.embedUrl, data.videoId);\n return;\n }\n\n if (\n data.type === 'ltiDeepLinkingResponse' ||\n data.messageType === 'LtiDeepLinkingResponse'\n ) {\n const contentItems = data.content_items || data.contentItems || [];\n if (contentItems.length > 0) {\n const item = contentItems[0];\n const embedUrl =\n item.url || item.embed_url || item.embedUrl || '';\n const videoId = item.id || item.mediaId || '';\n if (embedUrl) {\n this.selectIframeLibraryVideo(root, embedUrl, videoId);\n }\n }\n return;\n }\n\n if (data.action === 'selectMedia' || data.action === 'mediaSelected') {\n const embedUrl = data.embedUrl || data.url || '';\n if (embedUrl) {\n this.selectIframeLibraryVideo(root, embedUrl);\n }\n return;\n }\n }\n\n selectIframeLibraryVideo(root, embedUrl) {\n const form = root.querySelector(Selectors.IFRAME.elements.form);\n\n const urlInput = form.querySelector(Selectors.IFRAME.elements.url);\n urlInput.value = embedUrl;\n\n const configureTabItem = root.querySelector('.tiny_iframecms_tab_url_item');\n if (configureTabItem) {\n configureTabItem.style.display = '';\n }\n\n this.switchToUrlTab(root);\n this.updatePreview(root);\n }\n}\n"],"names":["constructor","editor","parseInput","input","trim","iframeMatch","match","this","parseEmbedUrl","startsWith","parseVideoUrl","url","urlObj","URL","baseUrl","protocol","host","pathname","searchParams","has","videoId","get","isEmbed","tParam","widthParam","heightParam","showTitle","linkTitle","showUserAvatar","width","parseInt","height","startAt","secondsToTimeString","includes","rawUrl","isLtiLaunch","isGeneric","e","seconds","mins","Math","floor","secs","toString","padStart","timeStringToSeconds","timeStr","parts","split","isNaN","parseWidthHeight","value","parsed","computeAspectRatioCSS","values","w","h","buildEmbedUrl","options","token","courseid","search","set","startAtEnabled","data","editorData","autoConvertOptions","getDefault","key","fallback","_this","isUpdating","undefined","elementid","getElement","id","isupdating","textLinkOnly","selectedIframe","getSelectedIframe","getCurrentIframeData","currentModal","IframeModal","create","title","component","templateContext","getTemplateContext","registerEventListeners","node","selection","getNode","nodeName","toLowerCase","getAttribute","iframe","querySelector","wrapper","closest","textLink","href","responsive","src","style","maxWidthMatch","aspectRatioMatch","maxWidth","wrapperMatch","rw","parseFloat","rh","round","getFormValues","root","form","Selectors","IFRAME","elements","checked","viewUrl","linkText","str","div","document","createElement","textContent","innerHTML","escapeHtml","hrefUrl","replace","context","aspectRatioCSS","html","Templates","renderForPromise","updateUrlField","previewContainer","preview","urlWarning","classList","add","remove","embedUrl","previewWidth","min","previewHeight","handleInputChange","clearTimeout","debounceTimer","setTimeout","updatePreview","handleWidthChange","widthInput","heightInput","newWidth","handleHeightChange","modal","getRoot","generateIframeHtml","paragraphWrapper","outerHTML","getBody","querySelectorAll","forEach","p","fire","insertContent","confirmMessage","window","confirm","hide","$root","addEventListener","selector","on","ModalEvents","save","handleDialogueSubmission","hidden","destroy","removeBtn","actions","handleRemove","iframeLibraryTabBtn","tabIframeLibraryBtn","preventDefault","stopPropagation","switchToIframeLibraryTab","handleIframeLibraryTabClick","$iframeLibraryTabBtn","jQuery","urlTabBtn","tabUrlBtn","switchToUrlTab","uploadMediaBtn","tabUploadMediaBtn","uploadUrl","ltiConfig","contentItemUrl","err","mediacmsBaseUrl","iframeLibraryUrl","pane","paneIframeLibrary","iframeEl","iframeLibraryFrame","placeholderEl","iframeLibraryPlaceholder","loadingEl","iframeLibraryLoading","loadHandler","handleIframeLibraryLoad","removeEventListener","registerIframeLibraryEventListeners","urlTabItem","urlPane","paneUrl","iframeLibraryPane","display","setAttribute","event","handleIframeLibraryMessage","loadIframeLibrary","loadIframeLibraryViaLti","loadIframeLibraryStatic","type","selectIframeLibraryVideo","messageType","action","contentItems","content_items","length","item","embed_url","mediaId","configureTabItem"],"mappings":"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"} \ No newline at end of file diff --git a/lms-plugins/mediacms-moodle/tiny/mediacms/amd/src/iframeembed.js b/lms-plugins/mediacms-moodle/tiny/mediacms/amd/src/iframeembed.js index 6af8ff04..d6f8f4ce 100755 --- a/lms-plugins/mediacms-moodle/tiny/mediacms/amd/src/iframeembed.js +++ b/lms-plugins/mediacms-moodle/tiny/mediacms/amd/src/iframeembed.js @@ -294,7 +294,15 @@ export default class IframeEmbed { const maxWidthMatch = style.match(/max-width:\s*(\d+(?:\.\d+)?)px/); const aspectRatioMatch = style.match(/aspect-ratio:\s*(\d+(?:\.\d+)?)\s*\/\s*(\d+(?:\.\d+)?)/); - const maxWidth = maxWidthMatch ? parseInt(maxWidthMatch[1]) : 560; + // Fall back to wrapper's max-width for content saved with the new template + // where max-width lives on the wrapper div rather than the iframe style. + let maxWidth = maxWidthMatch ? parseInt(maxWidthMatch[1]) : null; + if (!maxWidth) { + const wrapper = this.selectedIframe.closest('.tiny-mediacms-iframe-wrapper'); + const wrapperStyle = wrapper ? (wrapper.getAttribute('style') || '') : ''; + const wrapperMatch = wrapperStyle.match(/max-width:\s*(\d+(?:\.\d+)?)px/); + maxWidth = wrapperMatch ? parseInt(wrapperMatch[1]) : 560; + } let height = 315; if (aspectRatioMatch) { diff --git a/lms-plugins/mediacms-moodle/tiny/mediacms/templates/iframe_embed_output.mustache b/lms-plugins/mediacms-moodle/tiny/mediacms/templates/iframe_embed_output.mustache index a87e5958..27ec844c 100755 --- a/lms-plugins/mediacms-moodle/tiny/mediacms/templates/iframe_embed_output.mustache +++ b/lms-plugins/mediacms-moodle/tiny/mediacms/templates/iframe_embed_output.mustache @@ -28,4 +28,4 @@ "aspectRatioClass": "ratio-16-9" } }} -
+