%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/vacivi36/ava/lib/editor/tiny/plugins/media/amd/build/
Upload File :
Create Path :
Current File : /home/vacivi36/ava/lib/editor/tiny/plugins/media/amd/build/image.min.js.map

{"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 Templates from 'core/templates';\nimport {get_string as getString, get_strings as getStrings} from 'core/str';\nimport * as ModalFactory from 'core/modal_factory';\nimport Pending from 'core/pending';\nimport {displayFilepicker} from 'editor_tiny/utils';\nimport Selectors from './selectors';\nimport Modal from './imagemodal';\nimport {getImagePermissions} from './options';\nimport {component} from \"./common\";\n\nexport const MediaImage = class {\n\n    DEFAULTS = {\n        WIDTH: 160,\n        HEIGHT: 160,\n    };\n\n    form = null;\n    rawImageDimensions = null;\n    canShowFilePicker = false;\n    editor = null;\n    currentModal = null;\n    selectedImage = null;\n    imageAlignment = null;\n\n    constructor(editor) {\n        const permissions = getImagePermissions(editor);\n        this.canShowFilePicker = permissions.filepicker;\n        this.editor = editor;\n    }\n\n    async displayDialogue() {\n        // Reset the image dimensions.\n        this.rawImageDimensions = null;\n\n        const currentImageData = await this.getCurrentImageData();\n        const modal = await ModalFactory.create({\n            type: Modal.TYPE,\n            title: getString('imageproperties', 'tiny_media'),\n            templateContext: await this.getTemplateContext(currentImageData),\n            removeOnClose: true,\n            large: true,\n        });\n\n        this.currentModal = modal;\n        if (currentImageData && currentImageData.src) {\n            this.loadPreviewImage(currentImageData.src);\n        }\n\n        await this.registerEventListeners(modal);\n        modal.show();\n    }\n\n    async getAlignmentTitles() {\n        if (!this.alignmentTitles) {\n            const [top, middle, bottom] = await getStrings([\n                'alignment_top',\n                'alignment_middle',\n                'alignment_bottom',\n            ].map((key) => ({key, component})));\n\n            this.alignmentTitles = {\n                top,\n                middle,\n                bottom,\n            };\n        }\n\n        return this.alignmentTitles;\n    }\n\n    async getImageAlignment(selected = '') {\n        const titles = await this.getAlignmentTitles();\n        const alignments = [\n            {\n                text: titles.top,\n                value: 'align-top',\n            },\n            {\n                text: titles.middle,\n                value: 'align-middle',\n            },\n            {\n                text: titles.bottom,\n                value: 'align-bottom',\n            },\n        ];\n\n        if (selected) {\n            alignments.forEach((alignment, index, array) => {\n                if (alignment.value === selected) {\n                    array[index].selected = true;\n                }\n            });\n        }\n\n        return alignments;\n    }\n\n    async getTemplateContext(data) {\n        return {\n            elementid: this.editor.id,\n            showfilepicker: this.canShowFilePicker,\n            alignoptions: await this.getImageAlignment(),\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        if (properties.align) {\n            properties.alignoptions = await this.getImageAlignment(properties.align);\n        }\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    filePickerCallback(params, self) {\n        if (params.url) {\n            const input = self.form.querySelector(Selectors.IMAGE.elements.url);\n            input.value = params.url;\n\n            // Auto set the width and height.\n            self.form.querySelector(Selectors.IMAGE.elements.width).value = '';\n            self.form.querySelector(Selectors.IMAGE.elements.height).value = '';\n\n            // Load the preview image.\n            self.loadPreviewImage(params.url);\n        }\n    }\n\n    storeImageDimensions(image) {\n        // Store dimensions of the raw image, falling back to defaults for images without dimensions (e.g. SVG).\n        this.rawImageDimensions = {\n            width: image.width || this.DEFAULTS.WIDTH,\n            height: image.height || this.DEFAULTS.HEIGHT,\n        };\n\n        const getCurrentWidth = (element) => {\n            if (element.value === '') {\n                element.value = this.rawImageDimensions.width;\n            }\n            return element.value;\n        };\n        const getCurrentHeight = (element) => {\n            if (element.value === '') {\n                element.value = this.rawImageDimensions.height;\n            }\n            return element.value;\n        };\n\n        const widthInput = this.form.querySelector(Selectors.IMAGE.elements.width);\n        const currentWidth = getCurrentWidth(widthInput);\n\n        const heightInput = this.form.querySelector(Selectors.IMAGE.elements.height);\n        const currentHeight = getCurrentHeight(heightInput);\n\n        const preview = this.form.querySelector(Selectors.IMAGE.elements.preview);\n        preview.setAttribute('src', image.src);\n        preview.style.display = 'inline';\n\n        const constrain = this.form.querySelector(Selectors.IMAGE.elements.constrain);\n        if (this.isPercentageValue(currentWidth) && this.isPercentageValue(currentHeight)) {\n            constrain.checked = currentWidth === currentHeight;\n        } else if (image.width === 0 || image.height === 0) {\n            // If we don't have both dimensions of the image, we can't auto-size it, so disable control.\n            constrain.disabled = 'disabled';\n        } else {\n            // This is the same as comparing to 3 decimal places.\n            const widthRatio = Math.round(1000 * parseInt(currentWidth, 10) / image.width);\n            const heightRatio = Math.round(1000 * parseInt(currentHeight, 10) / image.height);\n            constrain.checked = widthRatio === heightRatio;\n        }\n    }\n\n    loadPreviewImage(url) {\n        const image = new Image();\n\n        image.addEventListener('error', () => {\n            const preview = this.form.querySelector(Selectors.IMAGE.elements.preview);\n            preview.style.display = 'none';\n        });\n        image.addEventListener('load', () => {\n            this.storeImageDimensions(image);\n            this.autoAdjustSize();\n        });\n\n        image.src = url;\n    }\n\n    urlChanged() {\n        const input = this.form.querySelector(Selectors.IMAGE.elements.url);\n\n        if (input.value) {\n            // Load the preview image.\n            this.loadPreviewImage(input.value);\n        }\n    }\n\n    hasErrorUrlField() {\n        const url = this.form.querySelector(Selectors.IMAGE.elements.url).value;\n        const urlError = url === '';\n        this.toggleVisibility(Selectors.IMAGE.elements.urlWarning, urlError);\n        this.toggleAriaInvalid([Selectors.IMAGE.elements.url], urlError);\n\n        return urlError;\n    }\n\n    hasErrorAltField() {\n        const alt = this.form.querySelector(Selectors.IMAGE.elements.alt).value;\n        const presentation = this.form.querySelector(Selectors.IMAGE.elements.presentation).checked;\n        const imageAltError = alt === '' && !presentation;\n        this.toggleVisibility(Selectors.IMAGE.elements.altWarning, imageAltError);\n        this.toggleAriaInvalid([Selectors.IMAGE.elements.alt, Selectors.IMAGE.elements.presentation], imageAltError);\n\n        return imageAltError;\n    }\n\n    toggleVisibility(selector, predicate) {\n        const elements = this.form.querySelectorAll(selector);\n        elements.forEach((element) => {\n            element.style.display = predicate ? 'block' : 'none';\n        });\n    }\n\n    toggleAriaInvalid(selectors, predicate) {\n        selectors.forEach((selector) => {\n            const elements = this.form.querySelectorAll(selector);\n            elements.forEach((element) => element.setAttribute('aria-invalid', predicate));\n        });\n    }\n\n    getAlignmentClass(alignment) {\n        return alignment;\n    }\n\n    updateWarning() {\n        const urlError = this.hasErrorUrlField();\n        const imageAltError = this.hasErrorAltField();\n\n        return urlError || imageAltError;\n    }\n\n    getImageContext() {\n        // Check if there are any accessibility issues.\n        if (this.updateWarning()) {\n            return null;\n        }\n\n        const classList = [];\n\n        const constrain = this.form.querySelector(Selectors.IMAGE.elements.constrain).value;\n        if (constrain) {\n            classList.push(Selectors.IMAGE.styles.responsive);\n        }\n\n        // Add the alignment class for the image.\n        const alignment = this.getAlignmentClass(this.form.querySelector(Selectors.IMAGE.elements.alignment).value);\n        classList.push(alignment);\n\n        return {\n            url: this.form.querySelector(Selectors.IMAGE.elements.url).value,\n            alt: this.form.querySelector(Selectors.IMAGE.elements.alt).value,\n            width: this.form.querySelector(Selectors.IMAGE.elements.width).value,\n            height: this.form.querySelector(Selectors.IMAGE.elements.height).value,\n            presentation: this.form.querySelector(Selectors.IMAGE.elements.presentation).checked,\n            customStyle: this.form.querySelector(Selectors.IMAGE.elements.customStyle).value,\n            classlist: classList.join(' '),\n        };\n    }\n\n    setImage() {\n        const pendingPromise = new Pending('tiny_media:setImage');\n        const url = this.form.querySelector(Selectors.IMAGE.elements.url).value;\n        if (url === '') {\n            return;\n        }\n\n        // Check if there are any accessibility issues.\n        if (this.updateWarning()) {\n            pendingPromise.resolve();\n            return;\n        }\n\n        // Check for invalid width or height.\n        const width = this.form.querySelector(Selectors.IMAGE.elements.width).value;\n        if (!this.isPercentageValue(width) && isNaN(parseInt(width, 10))) {\n            this.form.querySelector(Selectors.IMAGE.elements.width).focus();\n            pendingPromise.resolve();\n            return;\n        }\n\n        const height = this.form.querySelector(Selectors.IMAGE.elements.height).value;\n        if (!this.isPercentageValue(height) && isNaN(parseInt(height, 10))) {\n            this.form.querySelector(Selectors.IMAGE.elements.height).focus();\n            pendingPromise.resolve();\n            return;\n        }\n\n        Templates.render('tiny_media/image', this.getImageContext())\n        .then((html) => {\n            this.editor.insertContent(html);\n            this.currentModal.destroy();\n            pendingPromise.resolve();\n\n            return html;\n        })\n        .catch();\n    }\n\n    handleKeyupCharacterCount() {\n        const alt = this.form.querySelector(Selectors.IMAGE.elements.alt).value;\n        const current = this.form.querySelector('#currentcount');\n        current.innerHTML = alt.length;\n    }\n\n    autoAdjustSize(forceHeight = false) {\n        // If we do not know the image size, do not do anything.\n        if (!this.rawImageDimensions) {\n            return;\n        }\n\n        const widthField = this.form.querySelector(Selectors.IMAGE.elements.width);\n        const heightField = this.form.querySelector(Selectors.IMAGE.elements.height);\n        const normalizeFieldData = (fieldData) => {\n            fieldData.isPercentageValue = !!this.isPercentageValue(fieldData.field.value);\n            if (fieldData.isPercentageValue) {\n                fieldData.percentValue = parseInt(fieldData.field.value, 10);\n                fieldData.pixelSize = this.rawImageDimensions[fieldData.type] / 100 * fieldData.percentValue;\n            } else {\n                fieldData.pixelSize = parseInt(fieldData.field.value, 10);\n                fieldData.percentValue = fieldData.pixelSize / this.rawImageDimensions[fieldData.type] * 100;\n            }\n\n            return fieldData;\n        };\n\n        const getKeyField = () => {\n            const getValue = () => {\n                if (forceHeight) {\n                    return {\n                        field: heightField,\n                        type: 'height',\n                    };\n                } else {\n                    return {\n                        field: widthField,\n                        type: 'width',\n                    };\n                }\n            };\n\n            const currentValue = getValue();\n            if (currentValue.field.value === '') {\n                currentValue.field.value = this.rawImageDimensions[currentValue.type];\n            }\n\n            return normalizeFieldData(currentValue);\n        };\n\n        const getRelativeField = () => {\n            if (forceHeight) {\n                return normalizeFieldData({\n                    field: widthField,\n                    type: 'width',\n                });\n            } else {\n                return normalizeFieldData({\n                    field: heightField,\n                    type: 'height',\n                });\n            }\n        };\n\n\n        const setImageDimensions = (image, keyField, relativeField, forceHeight = false) => {\n            const getStyleValue = (field) => field.isPercentageValue ? `${field.percentValue}%` : `${field.pixelSize}px`;\n\n            // If the values are constrained, then only update the width.\n            if (forceHeight) {\n                if (keyField.type === 'width') {\n                    image.style.width = getStyleValue(keyField);\n                } else {\n                    image.style.width = getStyleValue(relativeField);\n                }\n            } else {\n                image.style[keyField.type] = getStyleValue(keyField);\n                image.style[relativeField.type] = getStyleValue(relativeField);\n            }\n        };\n\n        const imagePreview = this.form.querySelector(Selectors.IMAGE.elements.preview);\n        // Clear the existing preview sizes.\n        imagePreview.style.width = '';\n        imagePreview.style.height = '';\n\n        // Now update with the new values.\n        const constrainField = this.form.querySelector(Selectors.IMAGE.elements.constrain);\n        const keyField = getKeyField();\n        const relativeField = getRelativeField();\n        if (constrainField.checked) {\n            // We are keeping the image in proportion.\n            // Calculate the size for the relative field.\n            if (keyField.isPercentageValue) {\n                // In proportion, so the percentages are the same.\n                relativeField.field.value = keyField.field.value;\n                relativeField.percentValue = keyField.percentValue;\n            } else {\n                relativeField.pixelSize = Math.round(\n                    keyField.pixelSize / this.rawImageDimensions[keyField.type] * this.rawImageDimensions[relativeField.type]\n                );\n                relativeField.field.value = relativeField.pixelSize;\n            }\n        }\n        setImageDimensions(imagePreview, keyField, relativeField, !!constrainField.checked);\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            align: '',\n            presentation: false,\n        };\n\n        const getImageHeight = (image) => {\n            if (!this.isPercentageValue(String(image.height))) {\n                return parseInt(image.height, 10);\n            }\n\n            return image.height;\n        };\n\n        const getImageWidth = (image) => {\n            if (!this.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.removeLegacyAlignment(image);\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        const alignment = this.getAlignmentProperties(image, properties);\n        if (alignment) {\n            properties.align = alignment.value;\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    removeLegacyAlignment(imageNode) {\n        if (!imageNode.style.margin) {\n            // There is no margin therefore this cannot match any known alignments.\n            return imageNode;\n        }\n\n        Selectors.IMAGE.alignments.some(alignment => {\n            if (imageNode.style[alignment.name] !== alignment.value) {\n                // The name/value do not match. Skip.\n                return false;\n            }\n            const normalisedNode = document.createElement('div');\n            normalisedNode.style.margin = alignment.margin;\n            if (imageNode.style.margin !== normalisedNode.style.margin) {\n                // The margin does not match.\n                return false;\n            }\n\n            imageNode.classList.add(this.getAlignmentClass(alignment.value));\n            imageNode.style[alignment.name] = null;\n            imageNode.style.margin = null;\n\n            return true;\n        });\n\n        return imageNode;\n    }\n\n    getAlignmentProperties(image) {\n        const currentAlignment = Selectors.IMAGE.alignments.find((alignment) => {\n            if (image.classList.contains(this.getAlignmentClass(alignment.value))) {\n                return true;\n            }\n\n            if (alignment.legacyValues) {\n                return alignment.legacyValues.some((legacyValue) => image.classList.contains(legacyValue));\n            }\n\n            return false;\n        });\n        if (currentAlignment) {\n            return currentAlignment;\n        }\n\n        return Selectors.IMAGE.alignments.find((alignment) => alignment.isDefault);\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    isPercentageValue(value) {\n        return value.match(/\\d+%/);\n    }\n\n    async registerEventListeners(modal) {\n        await modal.getBody();\n        const root = modal.getRoot()[0];\n\n        this.form = root.querySelector(Selectors.IMAGE.elements.form);\n        root.addEventListener('click', (e) => {\n            const submitAction = e.target.closest(Selectors.IMAGE.actions.submit);\n            const imageBrowserAction = e.target.closest(Selectors.IMAGE.actions.imageBrowser);\n            if (submitAction) {\n                e.preventDefault();\n                this.setImage();\n            }\n            if (imageBrowserAction && this.canShowFilePicker) {\n                e.preventDefault();\n                displayFilepicker(this.editor, 'image').then((params) => {\n                    const self = this;\n                    this.filePickerCallback(params, self);\n\n                    return;\n                }).catch();\n            }\n        });\n\n        root.addEventListener('change', (e) => {\n            const urlEle = e.target.closest(Selectors.IMAGE.elements.url);\n            if (urlEle) {\n                this.hasErrorUrlField();\n            }\n\n            const presentationEle = e.target.closest(Selectors.IMAGE.elements.presentation);\n            if (presentationEle) {\n                this.hasErrorAltField();\n            }\n\n            const constrainEle = e.target.closest(Selectors.IMAGE.elements.constrain);\n            if (constrainEle) {\n                this.autoAdjustSize(true);\n            }\n        });\n\n        root.addEventListener('blur', (e) => {\n            if (e.target.nodeType === Node.ELEMENT_NODE) {\n                const urlEle = e.target.closest(Selectors.IMAGE.elements.url);\n                if (urlEle) {\n                    this.urlChanged();\n                }\n\n                const altEle = e.target.closest(Selectors.IMAGE.elements.alt);\n                if (altEle) {\n                    this.hasErrorAltField();\n                }\n\n                const widthEle = e.target.closest(Selectors.IMAGE.elements.width);\n                if (widthEle) {\n                    this.autoAdjustSize();\n                }\n\n                const heightEle = e.target.closest(Selectors.IMAGE.elements.height);\n                if (heightEle) {\n                    this.autoAdjustSize(true);\n                }\n            }\n        }, true);\n\n        // Character count.\n        root.addEventListener('keyup', (e) => {\n            const altEle = e.target.closest(Selectors.IMAGE.elements.alt);\n            if (altEle) {\n                this.handleKeyupCharacterCount();\n            }\n        });\n    }\n};\n"],"names":["constructor","editor","WIDTH","HEIGHT","permissions","canShowFilePicker","filepicker","rawImageDimensions","currentImageData","this","getCurrentImageData","modal","ModalFactory","create","type","Modal","TYPE","title","templateContext","getTemplateContext","removeOnClose","large","currentModal","src","loadPreviewImage","registerEventListeners","show","alignmentTitles","top","middle","bottom","map","key","component","selected","titles","getAlignmentTitles","alignments","text","value","forEach","alignment","index","array","data","elementid","id","showfilepicker","alignoptions","getImageAlignment","selectedImageProperties","getSelectedImageProperties","properties","align","haspreview","alt","presentation","filePickerCallback","params","self","url","form","querySelector","Selectors","IMAGE","elements","width","height","storeImageDimensions","image","DEFAULTS","currentWidth","element","getCurrentWidth","currentHeight","getCurrentHeight","preview","setAttribute","style","display","constrain","isPercentageValue","checked","disabled","widthRatio","Math","round","parseInt","heightRatio","Image","addEventListener","autoAdjustSize","urlChanged","input","hasErrorUrlField","urlError","toggleVisibility","urlWarning","toggleAriaInvalid","hasErrorAltField","imageAltError","altWarning","selector","predicate","querySelectorAll","selectors","getAlignmentClass","updateWarning","getImageContext","classList","push","styles","responsive","customStyle","classlist","join","setImage","pendingPromise","Pending","resolve","isNaN","focus","render","then","html","insertContent","destroy","catch","handleKeyupCharacterCount","innerHTML","length","forceHeight","widthField","heightField","normalizeFieldData","fieldData","field","percentValue","pixelSize","imagePreview","constrainField","keyField","currentValue","getKeyField","relativeField","getStyleValue","setImageDimensions","getSelectedImage","selectedImage","removeLegacyAlignment","cssText","String","getImageWidth","getImageHeight","getAlignmentProperties","getAttribute","imageNode","margin","some","name","normalisedNode","document","createElement","add","currentAlignment","find","contains","legacyValues","legacyValue","isDefault","imgElm","selection","getNode","figureElm","dom","getParent","select","nodeName","toUpperCase","isPlaceholderImage","hasAttribute","match","getBody","root","getRoot","e","submitAction","target","closest","actions","submit","imageBrowserAction","imageBrowser","preventDefault","nodeType","Node","ELEMENT_NODE"],"mappings":"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"}

Zerion Mini Shell 1.0