Proyectos de Subversion Moodle

Rev

Rev 1 | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

{"version":3,"file":"ui.min.js","sources":["../src/ui.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 H5P Content configuration.\n *\n * @module      tiny_h5p/ui\n * @copyright   2022 Andrew Lyons <andrew@nicols.co.uk>\n * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {displayFilepicker} from 'editor_tiny/utils';\nimport {component} from './common';\nimport {getPermissions} from './options';\n\nimport Config from 'core/config';\nimport {getList} from 'core/normalise';\nimport {renderForPromise} from 'core/templates';\nimport Modal from 'tiny_h5p/modal';\nimport ModalEvents from 'core/modal_events';\nimport Pending from 'core/pending';\nimport {getFilePicker} from 'editor_tiny/options';\n\nlet openingSelection = null;\n\nexport const handleAction = (editor) => {\n    openingSelection = editor.selection.getBookmark();\n    displayDialogue(editor);\n};\n\n/**\n * Get the template context for the dialogue.\n *\n * @param {Editor} editor\n * @param {object} data\n * @returns {object} data\n */\nconst getTemplateContext = (editor, data) => {\n    const permissions = getPermissions(editor);\n\n    const canShowFilePicker = typeof getFilePicker(editor, 'h5p') !== 'undefined';\n    const canUpload = (permissions.upload && canShowFilePicker) ?? false;\n    const canEmbed = permissions.embed ?? false;\n    const canUploadAndEmbed = canUpload && canEmbed;\n\n    return Object.assign({}, {\n        elementid: editor.id,\n        canUpload,\n        canEmbed,\n        canUploadAndEmbed,\n        showOptions: false,\n        fileURL: data?.url ?? '',\n        showDisplayOptions: false,\n    }, data);\n};\n\n/**\n * Get the URL from the submitted form.\n *\n * @param {FormNode} form\n * @param {string} submittedUrl\n * @returns {URL|null}\n */\nconst getUrlFromSubmission = (form, submittedUrl) => {\n    if (!submittedUrl || (!submittedUrl.startsWith(Config.wwwroot) && !isValidUrl(submittedUrl))) {\n        return null;\n    }\n\n    // Generate a URL Object for the submitted URL.\n    const url = new URL(submittedUrl);\n\n    const downloadElement = form.querySelector('[name=\"download\"]');\n    if (downloadElement?.checked) {\n        url.searchParams.append('export', 1);\n    }\n\n    const embedElement = form.querySelector('[name=\"embed\"]');\n    if (embedElement?.checked) {\n        url.searchParams.append('embed', 1);\n    }\n\n    const copyrightElement = form.querySelector('[name=\"copyright\"]');\n    if (copyrightElement?.checked) {\n        url.searchParams.append('copyright', 1);\n    }\n\n    return url;\n};\n\n/**\n * Verify if this could be a h5p URL.\n *\n * @param {string} url Url to verify\n * @return {boolean} whether this is a valid URL.\n */\nconst isValidUrl = (url) => {\n    const pattern = new RegExp('^(https?:\\\\/\\\\/)?' + // Protocol.\n        '((([a-z\\\\d]([a-z\\\\d-]*[a-z\\\\d])*)\\\\.)+[a-z]{2,}|' + // Domain name.\n        '((\\\\d{1,3}\\\\.){3}\\\\d{1,3}))' + // OR ip (v4) address.\n        '(\\\\:\\\\d+)?(\\\\/[-a-z\\\\d%_.~+]*)*'); // Port and path.\n    return !!pattern.test(url);\n};\n\nconst handleDialogueSubmission = async(editor, modal, data) => {\n    const pendingPromise = new Pending('tiny_h5p:handleDialogueSubmission');\n\n    const form = getList(modal.getRoot())[0].querySelector('form');\n    if (!form) {\n        // The form couldn't be found, which is weird.\n        // This should not happen.\n        // Display the dialogue again.\n        modal.destroy();\n        displayDialogue(editor, Object.assign({}, data));\n        pendingPromise.resolve();\n        return;\n    }\n\n    // Get the URL from the submitted form.\n    const submittedUrl = form.querySelector('input[name=\"url\"]').value;\n    const url = getUrlFromSubmission(form, submittedUrl);\n\n    if (!url) {\n        // The URL is invalid.\n        // Fill it in and represent the dialogue with an error.\n        modal.destroy();\n        displayDialogue(editor, Object.assign({}, data, {\n            url: submittedUrl,\n            invalidUrl: true,\n        }));\n        pendingPromise.resolve();\n        return;\n    }\n\n    const mobileAppAutoPlay = form.querySelector('[name=\"mobileappautoplay\"]')?.checked;\n\n    const content = await renderForPromise(`${component}/content`, {\n        url: url.toString(),\n        mobileAppAutoPlay,\n    });\n\n    editor.selection.moveToBookmark(openingSelection);\n    editor.execCommand('mceInsertContent', false, content.html);\n    editor.selection.moveToBookmark(openingSelection);\n    pendingPromise.resolve();\n};\n\nconst getCurrentH5PData = (currentH5P) => {\n    const data = {};\n    let url;\n    try {\n        url = new URL(currentH5P.textContent);\n    } catch (error) {\n        return data;\n    }\n\n    if (url.searchParams.has('export')) {\n        data.download = true;\n        data.showOptions = true;\n        url.searchParams.delete('export');\n    }\n\n    if (url.searchParams.has('embed')) {\n        data.embed = true;\n        data.showOptions = true;\n        url.searchParams.delete('embed');\n    }\n\n    if (url.searchParams.has('copyright')) {\n        data.copyright = true;\n        data.showOptions = true;\n        url.searchParams.delete('copyright');\n    }\n\n    if (currentH5P.dataset.mobileappAutoplay == 'true') {\n        data.mobileAppAutoPlay = true;\n        data.showDisplayOptions = true;\n    }\n\n     data.url = url.toString();\n\n    return data;\n};\n\nconst displayDialogue = async(editor, data = {}) => {\n    const selection = editor.selection.getNode();\n    const currentH5P = selection.closest('.h5p-placeholder');\n    if (currentH5P) {\n        Object.assign(data, getCurrentH5PData(currentH5P));\n    }\n\n    const modal = await Modal.create({\n        templateContext: getTemplateContext(editor, data),\n    });\n\n    const $root = modal.getRoot();\n    const root = $root[0];\n    $root.on(ModalEvents.save, (event, modal) => {\n        handleDialogueSubmission(editor, modal, data);\n    });\n\n    root.addEventListener('click', (e) => {\n        const filepickerButton = e.target.closest('[data-target=\"filepicker\"]');\n        if (filepickerButton) {\n            displayFilepicker(editor, 'h5p').then((params) => {\n                if (params.url !== '') {\n                    const input = root.querySelector('form input[name=\"url\"]');\n                    input.value = params.url;\n                }\n                return params;\n            })\n                .catch();\n        }\n    });\n};\n"],"names":["openingSelection","editor","selection","getBookmark","displayDialogue","getTemplateContext","data","permissions","canShowFilePicker","canUpload","upload","canEmbed","embed","canUploadAndEmbed","Object","assign","elementid","id","showOptions","fileURL","url","showDisplayOptions","isValidUrl","RegExp","test","handleDialogueSubmission","async","modal","pendingPromise","Pending","form","getRoot","querySelector","destroy","resolve","submittedUrl","value","startsWith","Config","wwwroot","URL","downloadElement","checked","searchParams","append","embedElement","copyrightElement","getUrlFromSubmission","invalidUrl","mobileAppAutoPlay","_form$querySelector","content","component","toString","moveToBookmark","execCommand","html","getCurrentH5PData","currentH5P","textContent","error","has","download","delete","copyright","dataset","mobileappAutoplay","getNode","closest","Modal","create","templateContext","$root","root","on","ModalEvents","save","event","addEventListener","e","target","then","params","catch"],"mappings":"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"}