%PDF- %PDF-
Direktori : /home/vacivi36/ava/lib/editor/tiny/plugins/media/amd/build/ |
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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"}