Proyectos de Subversion Moodle

Rev

Rev 11 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
{"version":3,"file":"image.min.js","sources":["../src/image.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 Image class for Moodle.\n *\n * @module      tiny_media/image\n * @copyright   2022 Huong Nguyen <huongnv13@gmail.com>\n * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Selectors from './selectors';\nimport ImageModal from './imagemodal';\nimport {getImagePermissions} from './options';\nimport {getFilePicker} from 'editor_tiny/options';\nimport {ImageInsert} from 'tiny_media/imageinsert';\nimport {ImageDetails} from 'tiny_media/imagedetails';\nimport {prefetchStrings} from 'core/prefetch';\nimport {getString} from 'core/str';\nimport {\n    body,\n    footer,\n    hideElements,\n    showElements,\n    isPercentageValue,\n} from './helpers';\nimport {MAX_LENGTH_ALT} from './imagehelpers';\n\nprefetchStrings('tiny_media', [\n    'imageurlrequired',\n    'sizecustom_help',\n]);\n\nexport default class MediaImage {\n    canShowFilePicker = false;\n    editor = null;\n    currentModal = null;\n    /**\n     * @type {HTMLElement|null} The root element.\n     */\n    root = null;\n\n    constructor(editor) {\n        const permissions = getImagePermissions(editor);\n        const options = getFilePicker(editor, 'image');\n        // Indicates whether the file picker can be shown.\n        this.canShowFilePicker = permissions.filepicker\n            && (typeof options !== 'undefined')\n            && Object.keys(options.repositories).length > 0;\n        // Indicates whether the drop zone area can be shown.\n        this.canShowDropZone = (typeof options !== 'undefined') &&\n            Object.values(options.repositories).some(repository => repository.type === 'upload');\n\n        this.editor = editor;\n    }\n\n    async displayDialogue() {\n        const currentImageData = await this.getCurrentImageData();\n        this.currentModal = await ImageModal.create();\n        this.root = this.currentModal.getRoot()[0];\n        if (currentImageData && currentImageData.src) {\n            this.loadPreviewImage(currentImageData.src);\n        } else {\n            this.loadInsertImage();\n        }\n    }\n\n    /**\n     * Displays an insert image view asynchronously.\n     *\n     * @returns {Promise<void>}\n     */\n    loadInsertImage = async function() {\n        const templateContext = {\n            elementid: this.editor.id,\n            showfilepicker: this.canShowFilePicker,\n            showdropzone: this.canShowDropZone,\n            bodyTemplate: Selectors.IMAGE.template.body.insertImageBody,\n            footerTemplate: Selectors.IMAGE.template.footer.insertImageFooter,\n            selector: Selectors.IMAGE.type,\n        };\n\n        Promise.all([body(templateContext, this.root), footer(templateContext, this.root)])\n            .then(() => {\n                const imageinsert = new ImageInsert(\n                    this.root,\n                    this.editor,\n                    this.currentModal,\n                    this.canShowFilePicker,\n                    this.canShowDropZone,\n                );\n                imageinsert.init();\n                return;\n            })\n            .catch(error => {\n                window.console.log(error);\n            });\n    };\n\n    async getTemplateContext(data) {\n        return {\n            elementid: this.editor.id,\n            showfilepicker: this.canShowFilePicker,\n            ...data,\n        };\n    }\n\n    async getCurrentImageData() {\n        const selectedImageProperties = this.getSelectedImageProperties();\n        if (!selectedImageProperties) {\n            return {};\n        }\n\n        const properties = {...selectedImageProperties};\n\n        if (properties.src) {\n            properties.haspreview = true;\n        }\n\n        if (!properties.alt) {\n            properties.presentation = true;\n        }\n\n        return properties;\n    }\n\n    /**\n     * Asynchronously loads and previews an image from the provided URL.\n     *\n     * @param {string} url - The URL of the image to load and preview.\n     * @returns {Promise<void>}\n     */\n    loadPreviewImage = async function(url) {\n        this.startImageLoading();\n        const image = new Image();\n        image.src = url;\n        image.addEventListener('error', async() => {\n            const urlWarningLabelEle = this.root.querySelector(Selectors.IMAGE.elements.urlWarning);\n            urlWarningLabelEle.innerHTML = await getString('imageurlrequired', 'tiny_media');\n            showElements(Selectors.IMAGE.elements.urlWarning, this.root);\n            this.stopImageLoading();\n        });\n\n        image.addEventListener('load', async() => {\n            const currentImageData = await this.getCurrentImageData();\n            let templateContext = await this.getTemplateContext(currentImageData);\n            templateContext.sizecustomhelpicon = {text: await getString('sizecustom_help', 'tiny_media')};\n            templateContext.bodyTemplate = Selectors.IMAGE.template.body.insertImageDetailsBody;\n            templateContext.footerTemplate = Selectors.IMAGE.template.footer.insertImageDetailsFooter;\n            templateContext.selector = Selectors.IMAGE.type;\n            templateContext.maxlengthalt = MAX_LENGTH_ALT;\n\n            Promise.all([body(templateContext, this.root), footer(templateContext, this.root)])\n                .then(() => {\n                    this.stopImageLoading();\n                    return;\n                })\n                .then(() => {\n                    const imagedetails = new ImageDetails(\n                        this.root,\n                        this.editor,\n                        this.currentModal,\n                        this.canShowFilePicker,\n                        this.canShowDropZone,\n                        url,\n                        image,\n                    );\n                    imagedetails.init();\n                    return;\n                })\n                .catch(error => {\n                    window.console.log(error);\n                });\n        });\n    };\n\n    getSelectedImageProperties() {\n        const image = this.getSelectedImage();\n        if (!image) {\n            this.selectedImage = null;\n            return null;\n        }\n\n        const properties = {\n            src: null,\n            alt: null,\n            width: null,\n            height: null,\n            presentation: false,\n            customStyle: '', // Custom CSS styles applied to the image.\n        };\n\n        const getImageHeight = (image) => {\n            if (!isPercentageValue(String(image.height))) {\n                return parseInt(image.height, 10);\n            }\n\n            return image.height;\n        };\n\n        const getImageWidth = (image) => {\n            if (!isPercentageValue(String(image.width))) {\n                return parseInt(image.width, 10);\n            }\n\n            return image.width;\n        };\n\n        // Get the current selection.\n        this.selectedImage = image;\n\n        properties.customStyle = image.style.cssText;\n\n        const width = getImageWidth(image);\n        if (width !== 0) {\n            properties.width = width;\n        }\n\n        const height = getImageHeight(image);\n        if (height !== 0) {\n            properties.height = height;\n        }\n\n        properties.src = image.getAttribute('src');\n        properties.alt = image.getAttribute('alt') || '';\n        properties.presentation = (image.getAttribute('role') === 'presentation');\n\n        return properties;\n    }\n\n    getSelectedImage() {\n        const imgElm = this.editor.selection.getNode();\n        const figureElm = this.editor.dom.getParent(imgElm, 'figure.image');\n        if (figureElm) {\n            return this.editor.dom.select('img', figureElm)[0];\n        }\n\n        if (imgElm && (imgElm.nodeName.toUpperCase() !== 'IMG' || this.isPlaceholderImage(imgElm))) {\n            return null;\n        }\n        return imgElm;\n    }\n\n    isPlaceholderImage(imgElm) {\n        if (imgElm.nodeName.toUpperCase() !== 'IMG') {\n            return false;\n        }\n\n        return (imgElm.hasAttribute('data-mce-object') || imgElm.hasAttribute('data-mce-placeholder'));\n    }\n\n    /**\n     * Displays the upload loader and disables UI elements while loading a file.\n     */\n    startImageLoading() {\n        showElements(Selectors.IMAGE.elements.loaderIcon, this.root);\n        hideElements(Selectors.IMAGE.elements.insertImage, this.root);\n    }\n\n    /**\n     * Displays the upload loader and disables UI elements while loading a file.\n     */\n    stopImageLoading() {\n        hideElements(Selectors.IMAGE.elements.loaderIcon, this.root);\n        showElements(Selectors.IMAGE.elements.insertImage, this.root);\n    }\n}\n"],"names":["constructor","editor","async","templateContext","elementid","this","id","showfilepicker","canShowFilePicker","showdropzone","canShowDropZone","bodyTemplate","Selectors","IMAGE","template","body","insertImageBody","footerTemplate","footer","insertImageFooter","selector","type","Promise","all","root","then","ImageInsert","currentModal","init","catch","error","window","console","log","url","startImageLoading","image","Image","src","addEventListener","querySelector","elements","urlWarning","innerHTML","stopImageLoading","currentImageData","getCurrentImageData","getTemplateContext","sizecustomhelpicon","text","insertImageDetailsBody","insertImageDetailsFooter","maxlengthalt","MAX_LENGTH_ALT","ImageDetails","permissions","options","filepicker","Object","keys","repositories","length","values","some","repository","ImageModal","create","getRoot","loadPreviewImage","loadInsertImage","data","selectedImageProperties","getSelectedImageProperties","properties","haspreview","alt","presentation","getSelectedImage","selectedImage","width","height","customStyle","style","cssText","String","parseInt","getImageWidth","getImageHeight","getAttribute","imgElm","selection","getNode","figureElm","dom","getParent","select","nodeName","toUpperCase","isPlaceholderImage","hasAttribute","loaderIcon","insertImage"],"mappings":"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"}