Proyectos de Subversion Moodle

Rev

Autoría | Ultima modificación | Ver Log |

{"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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"}