1441 |
ariadna |
1 |
{"version":3,"file":"embedhelpers.min.js","sources":["../../src/embed/embedhelpers.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Tiny media plugin embed helpers.\n *\n * This provides easy access to any classes without instantiating a new object.\n *\n * @module tiny_media/embed/embedhelpers\n * @copyright 2024 Stevani Andolo <stevani@hotmail.com.au>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Selectors from '../selectors';\nimport {getStrings} from 'core/str';\nimport {component} from \"../common\";\nimport {getCurrentLanguage, getMoodleLang} from 'editor_tiny/options';\nimport Ajax from 'core/ajax';\nimport {getFileName} from '../helpers';\n\n/**\n * Return template context for insert media.\n *\n * @param {object} props\n * @returns {object}\n */\nexport const insertMediaTemplateContext = (props) => {\n return {\n mediaType: props.mediaType,\n showDropzone: props.canShowDropZone,\n showFilePicker: props.canShowFilePicker,\n fileType: 'audio/video',\n };\n};\n\n/**\n * Return template context for insert media.\n *\n * @param {object} props\n * @returns {object}\n */\nexport const insertMediaThumbnailTemplateContext = (props) => {\n return {\n elementid: props.editor.id,\n showDropzone: props.canShowDropZone,\n showImageFilePicker: props.canShowImageFilePicker,\n bodyTemplate: Selectors.EMBED.template.body.insertMediaBody,\n footerTemplate: Selectors.EMBED.template.footer.insertMediaFooter,\n fileType: 'image',\n selector: Selectors.EMBED.type,\n };\n};\n\n/**\n * Return selected media type and element.\n *\n * @param {editor} editor\n * @returns {Array}\n */\nexport const getSelectedMediaElement = (editor) => {\n let mediaType = null;\n let selectedMedia = null;\n const mediaElm = editor.selection.getNode();\n\n if (!mediaElm) {\n mediaType = null;\n selectedMedia = null;\n } else if (mediaElm.nodeName.toLowerCase() === 'video' || mediaElm.nodeName.toLowerCase() === 'audio') {\n mediaType = mediaElm.nodeName.toLowerCase();\n selectedMedia = mediaElm;\n } else if (mediaElm.querySelector('video')) {\n mediaType = 'video';\n selectedMedia = mediaElm.querySelector('video');\n } else if (mediaElm.querySelector('audio')) {\n mediaType = 'audio';\n selectedMedia = mediaElm.querySelector('audio');\n } else if (mediaElm.nodeName.toLowerCase() === 'a') {\n selectedMedia = mediaElm;\n }\n\n return [mediaType, selectedMedia];\n};\n\n/**\n * Returns result of media filtering.\n *\n * @param {string} url\n * @param {string} contextId\n * @returns {string}\n */\nexport const fetchPreview = async(url, contextId) => {\n const request = {\n methodname: 'tiny_media_preview',\n args: {\n contextid: contextId, // Use the system one.\n content: url,\n }\n };\n const responseObj = await Ajax.call([request])[0];\n return responseObj.content;\n};\n\n/**\n * Returns media type.\n *\n * @param {string} url\n * @returns {string|null}\n */\nexport const checkMediaType = async(url) => {\n try {\n const response = await fetch(url, {method: 'HEAD'});\n const contentType = response.headers.get('Content-type');\n\n if (!contentType) {\n return null;\n }\n\n if (contentType.startsWith('video/')) {\n return 'video';\n } else if (contentType.startsWith('audio/')) {\n return 'audio';\n }\n\n return null;\n } catch (e) {\n return null;\n }\n};\n\n/**\n * Returns media title.\n *\n * @param {string} url\n * @param {object} props\n * @returns {string|null} String of media title.\n */\nexport const getMediaTitle = async(url, props) => {\n const extension = url.split('.').pop().split('?')[0];\n if (props.acceptedMediaTypes.includes(`.${extension}`)) {\n return getFileName(url);\n }\n\n return null;\n};\n\n/**\n * Return template context for media details.\n *\n * @param {object} props\n * @returns {object}\n */\nexport const mediaDetailsTemplateContext = async(props) => {\n const context = {\n bodyTemplate: Selectors.EMBED.template.body.mediaDetailsBody,\n footerTemplate: Selectors.EMBED.template.footer.mediaDetailsFooter,\n isLink: (props.mediaType === 'link'),\n isVideo: (props.mediaType === 'video'),\n showControl: (props.mediaType === 'video' || props.mediaType === 'audio'),\n isUpdating: props.isUpdating,\n isNewFileOrLinkUpload: (props.newMediaLink || props.newFileUpload),\n selector: Selectors.EMBED.type,\n };\n\n return {...context, ...props};\n};\n\n/**\n * Get help strings.\n *\n * @returns {object}\n */\nexport const getHelpStrings = async() => {\n const [\n subtitles,\n captions,\n descriptions,\n chapters,\n metadata,\n customsize,\n linkcustomsize,\n ] = await getStrings([\n 'subtitles_help',\n 'captions_help',\n 'descriptions_help',\n 'chapters_help',\n 'metadata_help',\n 'customsize_help',\n 'linkcustomsize_help',\n ].map((key) => ({\n key,\n component,\n })));\n\n return {\n subtitles,\n captions,\n descriptions,\n chapters,\n metadata,\n customsize,\n linkcustomsize,\n };\n};\n\n/**\n * Get current moodle languages.\n *\n * @param {editor} editor\n * @returns {object}\n */\nexport const prepareMoodleLang = (editor) => {\n const moodleLangs = getMoodleLang(editor);\n const currentLanguage = getCurrentLanguage(editor);\n\n const installed = Object.entries(moodleLangs.installed).map(([code, lang]) => ({\n lang,\n code,\n \"default\": code === currentLanguage,\n }));\n\n const available = Object.entries(moodleLangs.available).map(([code, lang]) => ({\n lang,\n code,\n \"default\": code === currentLanguage,\n }));\n\n return {\n installed,\n available,\n };\n};\n\n/**\n * Return moodle lang.\n *\n * @param {string} subtitleLang\n * @param {editor} editor\n * @returns {object|null}\n */\nexport const getMoodleLangObj = (subtitleLang, editor) => {\n const {available} = getMoodleLang(editor);\n\n if (available[subtitleLang]) {\n return {\n lang: subtitleLang,\n code: available[subtitleLang],\n };\n }\n\n return null;\n};\n\n/**\n * Get media data from the inserted media.\n *\n * @param {object} props\n * @returns {object}\n */\nexport const getEmbeddedMediaDetails = (props) => {\n const tracks = {\n subtitles: [],\n captions: [],\n descriptions: [],\n chapters: [],\n metadata: []\n };\n\n const mediaMetadata = props.root.querySelectorAll(Selectors.EMBED.elements.mediaMetadataTabPane);\n mediaMetadata.forEach(metaData => {\n const trackElements = metaData.querySelectorAll(Selectors.EMBED.elements.track);\n trackElements.forEach(track => {\n tracks[metaData.dataset.trackKind].push({\n src: track.querySelector(Selectors.EMBED.elements.url).value,\n srclang: track.querySelector(Selectors.EMBED.elements.trackLang).value,\n label: track.querySelector(Selectors.EMBED.elements.trackLabel).value,\n defaultTrack: track.querySelector(Selectors.EMBED.elements.trackDefault).checked,\n });\n });\n });\n\n const querySelector = (element) => props.root.querySelector(element);\n const mediaDataProps = {};\n mediaDataProps.media = {\n type: props.mediaType,\n sources: props.media,\n poster: props.media.poster ?? null,\n title: querySelector(Selectors.EMBED.elements.title).value,\n width: querySelector(Selectors.EMBED.elements.width).value,\n height: querySelector(Selectors.EMBED.elements.height).value,\n autoplay: querySelector(Selectors.EMBED.elements.mediaAutoplay).checked,\n loop: querySelector(Selectors.EMBED.elements.mediaLoop).checked,\n muted: querySelector(Selectors.EMBED.elements.mediaMute).checked,\n controls: querySelector(Selectors.EMBED.elements.mediaControl).checked,\n tracks,\n };\n mediaDataProps.link = false;\n return mediaDataProps;\n};\n\n/**\n * Check for video/audio attributes.\n *\n * @param {HTMLElement} elem\n * @param {string} attr Attribute name\n * @returns {boolean}\n */\nexport const hasAudioVideoAttr = (elem, attr) => {\n // As explained in MDL-64175, some OS (like Ubuntu), are removing the value for these attributes.\n // So in order to check if attr=\"true\", we need to check if the attribute exists and if the value is empty or true.\n return (elem.hasAttribute(attr) && (elem.getAttribute(attr) || elem.getAttribute(attr) === ''));\n};\n"],"names":["props","mediaType","showDropzone","canShowDropZone","showFilePicker","canShowFilePicker","fileType","elementid","editor","id","showImageFilePicker","canShowImageFilePicker","bodyTemplate","Selectors","EMBED","template","body","insertMediaBody","footerTemplate","footer","insertMediaFooter","selector","type","selectedMedia","mediaElm","selection","getNode","nodeName","toLowerCase","querySelector","async","url","contextId","request","methodname","args","contextid","content","Ajax","call","contentType","fetch","method","headers","get","startsWith","e","extension","split","pop","acceptedMediaTypes","includes","mediaDetailsBody","mediaDetailsFooter","isLink","isVideo","showControl","isUpdating","isNewFileOrLinkUpload","newMediaLink","newFileUpload","subtitles","captions","descriptions","chapters","metadata","customsize","linkcustomsize","map","key","component","moodleLangs","currentLanguage","installed","Object","entries","_ref","code","lang","available","_ref2","subtitleLang","tracks","root","querySelectorAll","elements","mediaMetadataTabPane","forEach","metaData","track","dataset","trackKind","push","src","value","srclang","trackLang","label","trackLabel","defaultTrack","trackDefault","checked","element","mediaDataProps","media","sources","poster","title","width","height","autoplay","mediaAutoplay","loop","mediaLoop","muted","mediaMute","controls","mediaControl","link","elem","attr","hasAttribute","getAttribute"],"mappings":"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"}
|