Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
{"version":3,"file":"embedinsert.min.js","sources":["../../src/embed/embedinsert.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 upload class.\n *\n * This handles the embed upload using url, drag-drop and repositories.\n *\n * @module      tiny_media/embed/embedinsert\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 {prefetchStrings} from 'core/prefetch';\nimport {getStrings} from 'core/str';\nimport {component} from \"../common\";\nimport {\n    setPropertiesFromData,\n    startMediaLoading,\n    stopMediaLoading,\n    showElements,\n} from '../helpers';\nimport Selectors from \"../selectors\";\nimport Dropzone from 'core/dropzone';\nimport uploadFile from 'editor_tiny/uploader';\nimport {EmbedHandler} from './embedhandler';\nimport {\n    getMediaTitle,\n    mediaDetailsTemplateContext,\n    checkMediaType,\n    fetchPreview,\n} from './embedhelpers';\nimport {EmbedPreview} from './embedpreview';\n\nprefetchStrings(component, [\n    'insertmedia',\n    'addmediafilesdrop',\n    'uploading',\n    'loadingmedia',\n]);\n\nexport class EmbedInsert {\n\n    constructor(data) {\n        setPropertiesFromData(this, data); // Creates dynamic properties based on \"data\" param.\n    }\n\n    /**\n     * Init the dropzone and lang strings.\n     */\n    init = async() => {\n        const langStringKeys = [\n            'insertmedia',\n            'addmediafilesdrop',\n            'uploading',\n            'loadingmedia',\n        ];\n        const langStringValues = await getStrings([...langStringKeys].map((key) => ({key, component})));\n        this.langStrings = Object.fromEntries(langStringKeys.map((key, index) => [key, langStringValues[index]]));\n        this.currentModal.setTitle(this.langStrings.insertmedia);\n\n        // Let's init the dropzone if canShowDropZone is true and mediaType is null.\n        if (this.canShowDropZone && !this.mediaType) {\n            const dropZoneEle = document.querySelector(Selectors.EMBED.elements.dropzoneContainer);\n            const dropZone = new Dropzone(\n                dropZoneEle,\n                this.acceptedMediaTypes,\n                files => {\n                    this.handleUploadedFile(files);\n                }\n            );\n\n            dropZone.setLabel(this.langStrings.addmediafilesdrop);\n            dropZone.init();\n        }\n    };\n\n    /**\n     * Loads and displays a preview media based on the provided URL, and handles media loading events.\n     *\n     * @param {string} url - The URL of the media to load and display.\n     */\n    loadMediaPreview = async(url) => {\n        this.originalUrl = url;\n        this.fetchedMediaLinkTitle = await getMediaTitle(url, this);\n\n        if (this.newMediaLink) { // Media added using url input.\n            this.filteredContent = await fetchPreview(this.originalUrl, this.contextId);\n\n            if (!this.mediaType) {\n                // It means the url points to a physical media file.\n                if (this.fetchedMediaLinkTitle) {\n                    // Case-insensitive regex for video tag.\n                    const videoRegex = /<video[^>]*>.*<\\/video>/i;\n                    // Case-insensitive regex for audio tag.\n                    const audioRegex = /<audio[^>]*>.*<\\/audio>/i;\n\n                    if (videoRegex.test(this.filteredContent)) {\n                        this.mediaType = 'video';\n                    } else if (audioRegex.test(this.filteredContent)) {\n                        this.mediaType = 'audio';\n                    }\n                } else {\n                    this.mediaType = 'link';\n                }\n            }\n\n            // Process the media preview.\n            this.processMediaPreview();\n        } else { // Media added using dropzone or repositories.\n            this.mediaType ??= await checkMediaType(url);\n\n            // Process the media preview.\n            this.processMediaPreview();\n        }\n    };\n\n    /**\n     * Process the media preview.\n     */\n    processMediaPreview = async() => {\n        // Let's combine the props.\n        setPropertiesFromData(\n            this,\n            await (new EmbedHandler(this)).getMediaTemplateContext()\n        );\n\n        // Construct templateContext for embed preview.\n        const templateContext = await mediaDetailsTemplateContext(this);\n\n        if (this.isUpdating && !this.newMediaLink) {\n            // Will be used to set the media title if it's in update state.\n            this.mediaTitle = templateContext.media.title;\n        }\n\n        // Load the media details and preview of the selected media.\n        (new EmbedHandler(this)).loadMediaDetails(new EmbedPreview(this), templateContext);\n    };\n\n    /**\n     * Updates the content of the loader icon.\n     *\n     * @param {HTMLElement} root - The root element containing the loader icon.\n     * @param {object} langStrings - An object containing language strings.\n     * @param {number|null} progress - The progress percentage (optional).\n     * @returns {void}\n     */\n    updateLoaderIcon = (root, langStrings, progress = null) => {\n        const loaderIconState = root.querySelector(Selectors.EMBED.elements.loaderIconContainer + ' div');\n        loaderIconState.innerHTML = (progress !== null) ?\n                               `${langStrings.uploading} ${Math.round(progress)}%` :\n                               langStrings.loadingmedia;\n    };\n\n    /**\n     * Handles media preview on file picker callback.\n     *\n     * @param {object} params Object of uploaded file\n     */\n    filePickerCallback = (params) => {\n        if (params.url) {\n            if (this.mediaType) {\n                // Set mediaType to \"null\" if it started with viewing embedded link, otherwise it will not be consistent.\n                this.mediaType = null;\n            }\n\n            // Flag as new file upload.\n            this.newFileUpload = true;\n\n            // Load the media preview.\n            this.loadMediaPreview(params.url);\n        }\n    };\n\n    /**\n     * Handles the uploaded file, initiates the upload process, and updates the UI during the upload.\n     *\n     * @param {FileList} files - The list of files to upload (usually from a file input field).\n     * @returns {Promise<void>} A promise that resolves when the file is uploaded and processed.\n     */\n    handleUploadedFile = async(files) => {\n        try {\n            startMediaLoading(this.root, Selectors.EMBED.type);\n            const fileURL = await uploadFile(this.editor, 'media', files[0], files[0].name, (progress) => {\n                this.updateLoaderIcon(this.root, this.langStrings, progress);\n            });\n\n            // Set the loader icon content to \"loading\" after the file upload completes.\n            this.updateLoaderIcon(this.root, this.langStrings);\n            this.filePickerCallback({url: fileURL});\n        } catch (error) {\n            // Handle the error.\n            const urlWarningLabelEle = this.root.querySelector(Selectors.EMBED.elements.urlWarning);\n            urlWarningLabelEle.innerHTML = error.error !== undefined ? error.error : error;\n            showElements(Selectors.EMBED.elements.urlWarning, this.root);\n            stopMediaLoading(this.root, Selectors.EMBED.type);\n        }\n    };\n}\n"],"names":["component","constructor","data","async","langStringKeys","langStringValues","map","key","langStrings","Object","fromEntries","index","currentModal","setTitle","this","insertmedia","canShowDropZone","mediaType","dropZoneEle","document","querySelector","Selectors","EMBED","elements","dropzoneContainer","dropZone","Dropzone","acceptedMediaTypes","files","handleUploadedFile","setLabel","addmediafilesdrop","init","originalUrl","url","fetchedMediaLinkTitle","newMediaLink","filteredContent","contextId","audioRegex","test","processMediaPreview","EmbedHandler","getMediaTemplateContext","templateContext","isUpdating","mediaTitle","media","title","loadMediaDetails","EmbedPreview","root","progress","loaderIconState","loaderIconContainer","innerHTML","uploading","Math","round","loadingmedia","params","newFileUpload","loadMediaPreview","type","fileURL","editor","name","updateLoaderIcon","filePickerCallback","error","urlWarning","undefined"],"mappings":"0zBA8CgBA,kBAAW,CACvB,cACA,oBACA,YACA,4CAKAC,YAAYC,mCAOLC,gBACGC,eAAiB,CACnB,cACA,oBACA,YACA,gBAEEC,uBAAyB,mBAAW,IAAID,gBAAgBE,KAAKC,OAAUA,IAAAA,IAAKP,UAAAA,+BAC7EQ,YAAcC,OAAOC,YAAYN,eAAeE,KAAI,CAACC,IAAKI,QAAU,CAACJ,IAAKF,iBAAiBM,gBAC3FC,aAAaC,SAASC,KAAKN,YAAYO,aAGxCD,KAAKE,kBAAoBF,KAAKG,UAAW,OACnCC,YAAcC,SAASC,cAAcC,mBAAUC,MAAMC,SAASC,mBAC9DC,SAAW,IAAIC,kBACjBR,YACAJ,KAAKa,oBACLC,aACSC,mBAAmBD,UAIhCH,SAASK,SAAShB,KAAKN,YAAYuB,mBACnCN,SAASO,oDASE7B,MAAAA,cACV8B,YAAcC,SACdC,4BAA8B,+BAAcD,IAAKpB,MAElDA,KAAKsB,aAAc,SACdC,sBAAwB,8BAAavB,KAAKmB,YAAanB,KAAKwB,YAE5DxB,KAAKG,aAEFH,KAAKqB,sBAAuB,OAItBI,WAAa,2BAFA,2BAIJC,KAAK1B,KAAKuB,sBAChBpB,UAAY,QACVsB,WAAWC,KAAK1B,KAAKuB,wBACvBpB,UAAY,mBAGhBA,UAAY,YAKpBwB,0BACF,kDACExB,4CAAAA,gBAAoB,gCAAeiB,WAGnCO,sEAOStC,6CAGdW,WACO,IAAI4B,2BAAa5B,MAAO6B,iCAI7BC,sBAAwB,6CAA4B9B,MAEtDA,KAAK+B,aAAe/B,KAAKsB,oBAEpBU,WAAaF,gBAAgBG,MAAMC,WAIvCN,2BAAa5B,MAAOmC,iBAAiB,IAAIC,2BAAapC,MAAO8B,6DAWnD,SAACO,KAAM3C,iBAAa4C,gEAAW,WACxCC,gBAAkBF,KAAK/B,cAAcC,mBAAUC,MAAMC,SAAS+B,oBAAsB,QAC1FD,gBAAgBE,UAA0B,OAAbH,mBACH5C,YAAYgD,sBAAaC,KAAKC,MAAMN,eACvC5C,YAAYmD,2DAQjBC,SACdA,OAAO1B,MACHpB,KAAKG,iBAEAA,UAAY,WAIhB4C,eAAgB,OAGhBC,iBAAiBF,OAAO1B,oDAUhB/B,MAAAA,2CAEKW,KAAKqC,KAAM9B,mBAAUC,MAAMyC,YACvCC,cAAgB,qBAAWlD,KAAKmD,OAAQ,QAASrC,MAAM,GAAIA,MAAM,GAAGsC,MAAOd,gBACxEe,iBAAiBrD,KAAKqC,KAAMrC,KAAKN,YAAa4C,kBAIlDe,iBAAiBrD,KAAKqC,KAAMrC,KAAKN,kBACjC4D,mBAAmB,CAAClC,IAAK8B,UAChC,MAAOK,OAEsBvD,KAAKqC,KAAK/B,cAAcC,mBAAUC,MAAMC,SAAS+C,YACzDf,eAA4BgB,IAAhBF,MAAMA,MAAsBA,MAAMA,MAAQA,gCAC5DhD,mBAAUC,MAAMC,SAAS+C,WAAYxD,KAAKqC,oCACtCrC,KAAKqC,KAAM9B,mBAAUC,MAAMyC,6CAvJ1BjD,KAAMZ"}