Merge branch 'MDL-85930-500' of https://github.com/andimendunia/moodle into MOODLE_500_STABLE
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,3 +1,3 @@
|
||||
define("tiny_media/embed/embedinsert",["exports","core/prefetch","core/str","../common","../helpers","../selectors","core/dropzone","editor_tiny/uploader","./embedhandler","./embedhelpers","./embedpreview"],(function(_exports,_prefetch,_str,_common,_helpers,_selectors,_dropzone,_uploader,_embedhandler,_embedhelpers,_embedpreview){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.EmbedInsert=void 0,_selectors=_interopRequireDefault(_selectors),_dropzone=_interopRequireDefault(_dropzone),_uploader=_interopRequireDefault(_uploader),(0,_prefetch.prefetchStrings)(_common.component,["insertmedia","addmediafilesdrop","uploading","loadingmedia"]);_exports.EmbedInsert=class{constructor(data){_defineProperty(this,"init",(async()=>{const langStringKeys=["insertmedia","addmediafilesdrop","uploading","loadingmedia"],langStringValues=await(0,_str.getStrings)([...langStringKeys].map((key=>({key:key,component:_common.component}))));if(this.langStrings=Object.fromEntries(langStringKeys.map(((key,index)=>[key,langStringValues[index]]))),this.currentModal.setTitle(this.langStrings.insertmedia),this.canShowDropZone&&!this.mediaType){const dropZoneEle=document.querySelector(_selectors.default.EMBED.elements.dropzoneContainer),dropZone=new _dropzone.default(dropZoneEle,this.acceptedMediaTypes,(files=>{this.handleUploadedFile(files)}));dropZone.setLabel(this.langStrings.addmediafilesdrop),dropZone.init()}})),_defineProperty(this,"loadMediaPreview",(async url=>{if(this.originalUrl=url,this.fetchedMediaLinkTitle=await(0,_embedhelpers.getMediaTitle)(url,this),this.newMediaLink){if(this.filteredContent=await(0,_embedhelpers.fetchPreview)(this.originalUrl,this.contextId),!this.mediaType)if(this.fetchedMediaLinkTitle){const audioRegex=/<audio[^>]*>.*<\/audio>/i;/<video[^>]*>.*<\/video>/i.test(this.filteredContent)?this.mediaType="video":audioRegex.test(this.filteredContent)&&(this.mediaType="audio")}else this.mediaType="link";this.processMediaPreview()}else{var _this$mediaType;null!==(_this$mediaType=this.mediaType)&&void 0!==_this$mediaType||(this.mediaType=await(0,_embedhelpers.checkMediaType)(url)),this.processMediaPreview()}})),_defineProperty(this,"processMediaPreview",(async()=>{(0,_helpers.setPropertiesFromData)(this,await new _embedhandler.EmbedHandler(this).getMediaTemplateContext());const templateContext=await(0,_embedhelpers.mediaDetailsTemplateContext)(this);this.isUpdating&&!this.newMediaLink&&(this.mediaTitle=templateContext.media.title),new _embedhandler.EmbedHandler(this).loadMediaDetails(new _embedpreview.EmbedPreview(this),templateContext)})),_defineProperty(this,"updateLoaderIcon",(function(root,langStrings){let progress=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;const loaderIconState=root.querySelector(_selectors.default.EMBED.elements.loaderIconContainer+" div");loaderIconState.innerHTML=null!==progress?"".concat(langStrings.uploading," ").concat(Math.round(progress),"%"):langStrings.loadingmedia})),_defineProperty(this,"filePickerCallback",(params=>{params.url&&(this.mediaType&&(this.mediaType=null),this.newFileUpload=!0,this.loadMediaPreview(params.url))})),_defineProperty(this,"handleUploadedFile",(async files=>{try{(0,_helpers.startMediaLoading)(this.root,_selectors.default.EMBED.type);const fileURL=await(0,_uploader.default)(this.editor,"media",files[0],files[0].name,(progress=>{this.updateLoaderIcon(this.root,this.langStrings,progress)}));this.updateLoaderIcon(this.root,this.langStrings),this.filePickerCallback({url:fileURL})}catch(error){this.root.querySelector(_selectors.default.EMBED.elements.urlWarning).innerHTML=void 0!==error.error?error.error:error,(0,_helpers.showElements)(_selectors.default.EMBED.elements.urlWarning,this.root),(0,_helpers.stopMediaLoading)(this.root,_selectors.default.EMBED.type)}})),(0,_helpers.setPropertiesFromData)(this,data)}}}));
|
||||
define("tiny_media/embed/embedinsert",["exports","core/prefetch","core/str","../common","../helpers","../selectors","core/dropzone","editor_tiny/uploader","./embedhandler","./embedhelpers","./embedpreview"],(function(_exports,_prefetch,_str,_common,_helpers,_selectors,_dropzone,_uploader,_embedhandler,_embedhelpers,_embedpreview){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.EmbedInsert=void 0,_selectors=_interopRequireDefault(_selectors),_dropzone=_interopRequireDefault(_dropzone),_uploader=_interopRequireDefault(_uploader),(0,_prefetch.prefetchStrings)(_common.component,["insertmedia","addmediafilesdrop","uploading","loadingmedia"]);_exports.EmbedInsert=class{constructor(data){_defineProperty(this,"init",(async()=>{const langStringKeys=["insertmedia","addmediafilesdrop","uploading","loadingmedia"],langStringValues=await(0,_str.getStrings)([...langStringKeys].map((key=>({key:key,component:_common.component}))));if(this.langStrings=Object.fromEntries(langStringKeys.map(((key,index)=>[key,langStringValues[index]]))),this.currentModal.setTitle(this.langStrings.insertmedia),this.canShowDropZone&&!this.mediaType){const dropZoneEle=document.querySelector(_selectors.default.EMBED.elements.dropzoneContainer),dropZone=new _dropzone.default(dropZoneEle,this.acceptedMediaTypes,(files=>{this.handleUploadedFile(files)}));dropZone.setLabel(this.langStrings.addmediafilesdrop),dropZone.init()}})),_defineProperty(this,"loadMediaPreview",(async url=>{const parsedUrl=new URL(url);if(this.fetchedMediaLinkTitle=await(0,_embedhelpers.getMediaTitle)(url,this),this.originalUrl=parsedUrl.hash?parsedUrl.toString().split("#")[0]:parsedUrl.toString(),this.newMediaLink){if(this.filteredContent=await(0,_embedhelpers.fetchPreview)(this.originalUrl,this.contextId),!this.mediaType)if(this.filteredContent&&""!==this.filteredContent.trim())this.mediaType="link";else if(this.fetchedMediaLinkTitle){const audioRegex=/<audio[^>]*>.*<\/audio>/i;/<video[^>]*>.*<\/video>/i.test(this.filteredContent)?this.mediaType="video":audioRegex.test(this.filteredContent)&&(this.mediaType="audio")}this.processMediaPreview()}else{var _this$mediaType;null!==(_this$mediaType=this.mediaType)&&void 0!==_this$mediaType||(this.mediaType=await(0,_embedhelpers.checkMediaType)(url)),this.mediaType||(this.filteredContent=await(0,_embedhelpers.fetchPreview)(this.originalUrl,this.contextId),this.filteredContent&&""!==this.filteredContent.trim()&&(this.mediaType="link")),this.processMediaPreview()}})),_defineProperty(this,"processMediaPreview",(async()=>{(0,_helpers.setPropertiesFromData)(this,await new _embedhandler.EmbedHandler(this).getMediaTemplateContext());const templateContext=await(0,_embedhelpers.mediaDetailsTemplateContext)(this);this.isUpdating&&!this.newMediaLink&&(this.mediaTitle=templateContext.media.title),new _embedhandler.EmbedHandler(this).loadMediaDetails(new _embedpreview.EmbedPreview(this),templateContext)})),_defineProperty(this,"updateLoaderIcon",(function(root,langStrings){let progress=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;const loaderIconState=root.querySelector(_selectors.default.EMBED.elements.loaderIconContainer+" div");loaderIconState.innerHTML=null!==progress?"".concat(langStrings.uploading," ").concat(Math.round(progress),"%"):langStrings.loadingmedia})),_defineProperty(this,"filePickerCallback",(params=>{params.url&&(this.mediaType&&(this.mediaType=null),this.newFileUpload=!0,this.loadMediaPreview(params.url))})),_defineProperty(this,"handleUploadedFile",(async files=>{try{(0,_helpers.startMediaLoading)(this.root,_selectors.default.EMBED.type);const fileURL=await(0,_uploader.default)(this.editor,"media",files[0],files[0].name,(progress=>{this.updateLoaderIcon(this.root,this.langStrings,progress)}));this.updateLoaderIcon(this.root,this.langStrings),this.filePickerCallback({url:fileURL})}catch(error){this.root.querySelector(_selectors.default.EMBED.elements.urlWarning).innerHTML=void 0!==error.error?error.error:error,(0,_helpers.showElements)(_selectors.default.EMBED.elements.urlWarning,this.root),(0,_helpers.stopMediaLoading)(this.root,_selectors.default.EMBED.type)}})),(0,_helpers.setPropertiesFromData)(this,data)}}}));
|
||||
|
||||
//# sourceMappingURL=embedinsert.min.js.map
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
@@ -5,6 +5,6 @@ define("tiny_media/helpers",["exports","core/templates","./selectors","core/conf
|
||||
* @module tiny_media/helpers
|
||||
* @copyright 2024 Stevani Andolo <stevani@hotmail.com.au>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.stopMediaLoading=_exports.startMediaLoading=_exports.sourceTypeChecked=_exports.showElements=_exports.setPropertiesFromData=_exports.setFilenameLabel=_exports.isValidUrl=_exports.isPercentageValue=_exports.isExternalUrl=_exports.hideElements=_exports.getFileName=_exports.footer=_exports.body=void 0,_templates=_interopRequireDefault(_templates),_selectors=_interopRequireDefault(_selectors),_config=_interopRequireDefault(_config);_exports.body=async(templateContext,root)=>_templates.default.renderForPromise(templateContext.bodyTemplate,{...templateContext}).then((_ref=>{let{html:html,js:js}=_ref;_templates.default.replaceNodeContents(root.querySelector(_selectors.default[templateContext.selector].elements.bodyTemplate),html,js)})).catch((error=>{window.console.log(error)}));_exports.footer=async(templateContext,root)=>_templates.default.renderForPromise(templateContext.footerTemplate,{...templateContext}).then((_ref2=>{let{html:html,js:js}=_ref2;_templates.default.replaceNodeContents(root.querySelector(_selectors.default[templateContext.selector].elements.footerTemplate),html,js)})).catch((error=>{window.console.log(error)}));_exports.setPropertiesFromData=async(instance,data)=>{for(const property in data)"function"!=typeof data[property]&&(instance[property]=data[property]);return instance};_exports.isValidUrl=urlString=>!!new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3})|localhost)(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*").test(urlString);const hideElements=(elements,root)=>{if(elements instanceof Array)elements.forEach((elementSelector=>{const element=root.querySelector(elementSelector);element&&element.classList.add("d-none")}));else{const element=root.querySelector(elements);element&&element.classList.add("d-none")}};_exports.hideElements=hideElements;const showElements=(elements,root)=>{if(elements instanceof Array)elements.forEach((elementSelector=>{const element=root.querySelector(elementSelector);element&&element.classList.remove("d-none")}));else{const element=root.querySelector(elements);element&&element.classList.remove("d-none")}};_exports.showElements=showElements;_exports.startMediaLoading=(root,selector)=>{showElements(_selectors.default[selector].elements.loaderIcon,root);const elementsToHide=[_selectors.default[selector].elements.insertMedia,_selectors.default[selector].elements.urlWarning,_selectors.default[selector].elements.modalFooter];hideElements(elementsToHide,root)};_exports.stopMediaLoading=(root,selector)=>{hideElements(_selectors.default[selector].elements.loaderIcon,root);const elementsToShow=[_selectors.default[selector].elements.insertMedia,_selectors.default[selector].elements.modalFooter];showElements(elementsToShow,root)};const isExternalUrl=url=>!1===new RegExp("".concat(_config.default.wwwroot)).test(url);_exports.isExternalUrl=isExternalUrl;const setFilenameLabel=props=>{const urlLabelEle=props.root.querySelector(props.fileNameSelector);urlLabelEle&&(urlLabelEle.innerHTML=props.label,urlLabelEle.setAttribute("title",props.label))};_exports.setFilenameLabel=setFilenameLabel;_exports.sourceTypeChecked=props=>{if(props.fetchedTitle)props.label=props.fetchedTitle;else if(isExternalUrl(props.source))props.label=decodeURI(props.source);else{const filename=props.source.split("/").pop().split("?")[0];props.label=decodeURI(filename)}setFilenameLabel(props)};_exports.getFileName=fileLabel=>{if(fileLabel.includes("/")){const split=fileLabel.split("/");let fileName=split[split.length-1];return fileName=fileName.split("."),fileName.length>1?decodeURI(fileName.slice(0,fileName.length-1).join(".")):decodeURI(fileName[0])}return decodeURI(fileLabel.split(".")[0])};_exports.isPercentageValue=value=>value.match(/\d+%/)}));
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.stopMediaLoading=_exports.startMediaLoading=_exports.sourceTypeChecked=_exports.showElements=_exports.setPropertiesFromData=_exports.setFilenameLabel=_exports.isValidUrl=_exports.isPercentageValue=_exports.isExternalUrl=_exports.hideElements=_exports.getFileName=_exports.footer=_exports.body=void 0,_templates=_interopRequireDefault(_templates),_selectors=_interopRequireDefault(_selectors),_config=_interopRequireDefault(_config);_exports.body=async(templateContext,root)=>_templates.default.renderForPromise(templateContext.bodyTemplate,{...templateContext}).then((_ref=>{let{html:html,js:js}=_ref;_templates.default.replaceNodeContents(root.querySelector(_selectors.default[templateContext.selector].elements.bodyTemplate),html,js)})).catch((error=>{window.console.log(error)}));_exports.footer=async(templateContext,root)=>_templates.default.renderForPromise(templateContext.footerTemplate,{...templateContext}).then((_ref2=>{let{html:html,js:js}=_ref2;_templates.default.replaceNodeContents(root.querySelector(_selectors.default[templateContext.selector].elements.footerTemplate),html,js)})).catch((error=>{window.console.log(error)}));_exports.setPropertiesFromData=async(instance,data)=>{for(const property in data)"function"!=typeof data[property]&&(instance[property]=data[property]);return instance};_exports.isValidUrl=urlString=>!!new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3})|localhost)(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*").test(urlString);const hideElements=(elements,root)=>{if(elements instanceof Array)elements.forEach((elementSelector=>{const element=root.querySelector(elementSelector);element&&element.classList.add("d-none")}));else{const element=root.querySelector(elements);element&&element.classList.add("d-none")}};_exports.hideElements=hideElements;const showElements=(elements,root)=>{if(elements instanceof Array)elements.forEach((elementSelector=>{const element=root.querySelector(elementSelector);element&&element.classList.remove("d-none")}));else{const element=root.querySelector(elements);element&&element.classList.remove("d-none")}};_exports.showElements=showElements;_exports.startMediaLoading=(root,selector)=>{showElements(_selectors.default[selector].elements.loaderIcon,root);const elementsToHide=[_selectors.default[selector].elements.insertMedia,_selectors.default[selector].elements.urlWarning,_selectors.default[selector].elements.modalFooter];hideElements(elementsToHide,root)};_exports.stopMediaLoading=(root,selector)=>{hideElements(_selectors.default[selector].elements.loaderIcon,root);const elementsToShow=[_selectors.default[selector].elements.insertMedia,_selectors.default[selector].elements.modalFooter];showElements(elementsToShow,root)};const isExternalUrl=url=>!1===new RegExp("".concat(_config.default.wwwroot)).test(url);_exports.isExternalUrl=isExternalUrl;const setFilenameLabel=props=>{const urlLabelEle=props.root.querySelector(props.fileNameSelector);urlLabelEle&&(urlLabelEle.innerHTML=props.label,urlLabelEle.setAttribute("title",props.label))};_exports.setFilenameLabel=setFilenameLabel;_exports.sourceTypeChecked=props=>{if(isExternalUrl(props.source))props.label=decodeURI(props.source);else{const filename=props.source.split("/").pop().split("?")[0];props.label=decodeURI(filename)}setFilenameLabel(props)};_exports.getFileName=fileLabel=>{if(fileLabel.includes("/")){const split=fileLabel.split("/");let fileName=split[split.length-1];return fileName=fileName.split("."),fileName.length>1?decodeURI(fileName.slice(0,fileName.length-1).join(".")):decodeURI(fileName[0])}return decodeURI(fileLabel.split(".")[0])};_exports.isPercentageValue=value=>value.match(/\d+%/)}));
|
||||
|
||||
//# sourceMappingURL=helpers.min.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -147,11 +147,21 @@ export const checkMediaType = async(url) => {
|
||||
* @returns {string|null} String of media title.
|
||||
*/
|
||||
export const getMediaTitle = async(url, props) => {
|
||||
const extension = url.split('.').pop().split('?')[0];
|
||||
if (props.acceptedMediaTypes.includes(`.${extension}`)) {
|
||||
const parsedUrl = new URL(url);
|
||||
|
||||
// Try get the title via the file name.
|
||||
const pathName = parsedUrl.pathname;
|
||||
const extension = pathName.includes('.') ? pathName.split('.').pop() : null;
|
||||
if (extension && props.acceptedMediaTypes.includes(`.${extension}`)) {
|
||||
return getFileName(url);
|
||||
}
|
||||
|
||||
// Try and get the title from the value after the '#'.
|
||||
const hashTitle = parsedUrl.hash ? parsedUrl.hash.substring(1) : null;
|
||||
if (hashTitle) {
|
||||
return hashTitle;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
@@ -93,15 +93,20 @@ export class EmbedInsert {
|
||||
* @param {string} url - The URL of the media to load and display.
|
||||
*/
|
||||
loadMediaPreview = async(url) => {
|
||||
this.originalUrl = url;
|
||||
const parsedUrl = new URL(url);
|
||||
this.fetchedMediaLinkTitle = await getMediaTitle(url, this);
|
||||
// The hash in a URL can cause issues. Remove it.
|
||||
this.originalUrl = parsedUrl.hash ? parsedUrl.toString().split('#')[0] : parsedUrl.toString();
|
||||
|
||||
if (this.newMediaLink) { // Media added using url input.
|
||||
this.filteredContent = await fetchPreview(this.originalUrl, this.contextId);
|
||||
|
||||
if (!this.mediaType) {
|
||||
// It means the url points to a physical media file.
|
||||
if (this.fetchedMediaLinkTitle) {
|
||||
// If the filtered content is not empty, it means Moodle's filter recognized it as external media.
|
||||
if (this.filteredContent && this.filteredContent.trim() !== '') {
|
||||
this.mediaType = 'link';
|
||||
} else if (this.fetchedMediaLinkTitle) {
|
||||
// It means the url points to a physical media file with a hash-based title.
|
||||
// Case-insensitive regex for video tag.
|
||||
const videoRegex = /<video[^>]*>.*<\/video>/i;
|
||||
// Case-insensitive regex for audio tag.
|
||||
@@ -112,8 +117,6 @@ export class EmbedInsert {
|
||||
} else if (audioRegex.test(this.filteredContent)) {
|
||||
this.mediaType = 'audio';
|
||||
}
|
||||
} else {
|
||||
this.mediaType = 'link';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +125,15 @@ export class EmbedInsert {
|
||||
} else { // Media added using dropzone or repositories.
|
||||
this.mediaType ??= await checkMediaType(url);
|
||||
|
||||
// If checkMediaType returns null, try fetching preview to detect external media providers.
|
||||
if (!this.mediaType) {
|
||||
this.filteredContent = await fetchPreview(this.originalUrl, this.contextId);
|
||||
// If the filtered content is not empty, it means Moodle's filter recognized it as external media.
|
||||
if (this.filteredContent && this.filteredContent.trim() !== '') {
|
||||
this.mediaType = 'link';
|
||||
}
|
||||
}
|
||||
|
||||
// Process the media preview.
|
||||
this.processMediaPreview();
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ export class EmbedPreview extends MediaBase {
|
||||
}
|
||||
}
|
||||
|
||||
return fileName;
|
||||
return decodeURI(fileName);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -201,19 +201,16 @@ export const setFilenameLabel = (props) => {
|
||||
* @param {object} props
|
||||
*/
|
||||
export const sourceTypeChecked = (props) => {
|
||||
if (props.fetchedTitle) {
|
||||
props.label = props.fetchedTitle;
|
||||
if (!isExternalUrl(props.source)) {
|
||||
// Split the URL by '/' to get an array of segments.
|
||||
const segments = props.source.split('/');
|
||||
// Get the last segment, which should be the filename.
|
||||
const filename = segments.pop().split('?')[0];
|
||||
// Show the file name.
|
||||
props.label = decodeURI(filename);
|
||||
} else {
|
||||
if (!isExternalUrl(props.source)) {
|
||||
// Split the URL by '/' to get an array of segments.
|
||||
const segments = props.source.split('/');
|
||||
// Get the last segment, which should be the filename.
|
||||
const filename = segments.pop().split('?')[0];
|
||||
// Show the file name.
|
||||
props.label = decodeURI(filename);
|
||||
} else {
|
||||
props.label = decodeURI(props.source);
|
||||
}
|
||||
// For external URLs, always show the full URL in the footer for consistency.
|
||||
props.label = decodeURI(props.source);
|
||||
}
|
||||
setFilenameLabel(props);
|
||||
};
|
||||
|
||||
@@ -213,7 +213,7 @@ class repository_youtube extends repository {
|
||||
|
||||
foreach ($response['items'] as $result) {
|
||||
$title = $result->snippet->title;
|
||||
$source = 'http://www.youtube.com/v/' . $result->id->videoId . '#' . $title;
|
||||
$source = 'https://www.youtube.com/watch?v=' . $result->id->videoId . '#' . $title;
|
||||
$thumb = $result->snippet->getThumbnails()->getDefault();
|
||||
|
||||
$list[] = array(
|
||||
|
||||
Reference in New Issue
Block a user