{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imageupload/imageuploadui.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imageupload/imageuploadprogress.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imageupload/imageuploadediting.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imageupload.js"],"names":["ImageUploadUI","editor","this","t","componentCreator","locale","view","FileDialogButtonView","command","commands","get","imageTypes","config","imageTypesRegExp","createImageTypeRegExp","set","acceptedType","map","type","concat","join","allowMultipleFiles","buttonView","label","icon","icons","image","tooltip","bind","to","on","evt","files","imagesToUpload","Array","from","filter","file","test","length","execute","ui","componentFactory","add","Plugin","ImageUploadProgress","_this","Object","classCallCheck","_super","call","placeholder","encodeURIComponent","uploadingPlaceholder","_this2","plugins","has","editing","downcastDispatcher","uploadStatusChange","apply","arguments","data","conversionApi","modelImage","item","uploadId","getAttribute","consumable","consume","name","imageUtils","fileRepository","FileRepository","status","attributeNewValue","viewFigure","mapper","toViewElement","viewWriter","writer","_startAppearEffect","_showPlaceholder","loader","loaders","_hidePlaceholder","_showProgressBar","_displayLocalImage","_showCompleteIcon","_hideProgressBar","_stopAppearEffect","hasClass","addClass","removeClass","viewImg","findViewImgElement","setAttribute","_getUIElement","insert","createPositionAfter","_createPlaceholder","_removeUIElement","progressBar","_createProgressBar","createPositionAt","value","change","setStyle","completeIcon","createUIElement","class","setTimeout","remove","createRangeOn","setCustomProperty","imageFigure","uniqueProperty","_step","_iterator","_createForOfIteratorHelper","getChildren","s","n","done","child","getCustomProperty","err","e","f","element","ImageUploadEditing","define","upload","types","_uploadImageElements","Map","doc","model","document","conversion","uploadImageCommand","UploadImageCommand","for","attributeToAttribute","key","listenTo","isHtmlIncluded","dataTransfer","images","stop","targetRanges","setSelection","viewRange","toModelRange","enqueueChange","fetchableImages","createRangeIn","content","isLocalImage","promise","fetchLocalImage","imageElement","UpcastWriter","imageuploadediting_createForOfIteratorHelper","fetchableImage","createLoader","id","preventDefault","_step2","changes","differ","getChanges","includeChangesInGraveyard","reverse","insertedImagesIds","Set","_iterator2","entry","_step3","position","nodeAfter","isInsertedInGraveyard","root","rootName","_iterator3","getImagesFromChangeItem","abort","_readAndUpload","_ref","urls","default","_parseAndSetSrcsetAttributeOnImage","priority","schema","extend","allowAttributes","_this3","notification","Notification","imageUploadElements","read","then","env","isSafari","once","parent","domFigure","domConverter","mapViewToDom","originalDisplay","style","display","_ckHack","offsetHeight","fire","clean","catch","error","showWarning","title","namespace","removeAttribute","delete","destroyLoader","maxWidth","srcsetAttribute","keys","width","parseInt","isNaN","Math","max","ClipboardPipeline","ImageUtils","includes","getData","isImage","ImageUpload"],"mappings":"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","file":"js/chunk-2d0d6332.9e3563a5.js","sourcesContent":["/**\n * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageupload/imageuploadui\n */\n\nimport { Plugin, icons } from 'ckeditor5/src/core';\nimport { FileDialogButtonView } from 'ckeditor5/src/upload';\nimport { createImageTypeRegExp } from './utils';\n\n/**\n * The image upload button plugin.\n *\n * For a detailed overview, check the {@glink features/images/image-upload/image-upload Image upload feature} documentation.\n *\n * Adds the `'uploadImage'` button to the {@link module:ui/componentfactory~ComponentFactory UI component factory}\n * and also the `imageUpload` button as an alias for backward compatibility.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageUploadUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageUploadUI';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\t\tconst componentCreator = locale => {\n\t\t\tconst view = new FileDialogButtonView( locale );\n\t\t\tconst command = editor.commands.get( 'uploadImage' );\n\t\t\tconst imageTypes = editor.config.get( 'image.upload.types' );\n\t\t\tconst imageTypesRegExp = createImageTypeRegExp( imageTypes );\n\n\t\t\tview.set( {\n\t\t\t\tacceptedType: imageTypes.map( type => `image/${ type }` ).join( ',' ),\n\t\t\t\tallowMultipleFiles: true\n\t\t\t} );\n\n\t\t\tview.buttonView.set( {\n\t\t\t\tlabel: t( 'Insert image' ),\n\t\t\t\ticon: icons.image,\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\tview.buttonView.bind( 'isEnabled' ).to( command );\n\n\t\t\tview.on( 'done', ( evt, files ) => {\n\t\t\t\tconst imagesToUpload = Array.from( files ).filter( file => imageTypesRegExp.test( file.type ) );\n\n\t\t\t\tif ( imagesToUpload.length ) {\n\t\t\t\t\teditor.execute( 'uploadImage', { file: imagesToUpload } );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\treturn view;\n\t\t};\n\n\t\t// Setup `uploadImage` button and add `imageUpload` button as an alias for backward compatibility.\n\t\teditor.ui.componentFactory.add( 'uploadImage', componentCreator );\n\t\teditor.ui.componentFactory.add( 'imageUpload', componentCreator );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageupload/imageuploadprogress\n */\n\n/* globals setTimeout */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { FileRepository } from 'ckeditor5/src/upload';\n\nimport uploadingPlaceholder from '../../theme/icons/image_placeholder.svg';\n\nimport '../../theme/imageuploadprogress.css';\nimport '../../theme/imageuploadicon.css';\nimport '../../theme/imageuploadloader.css';\n\n/**\n * The image upload progress plugin.\n * It shows a placeholder when the image is read from the disk and a progress bar while the image is uploading.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageUploadProgress extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageUploadProgress';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The image placeholder that is displayed before real image data can be accessed.\n\t\t *\n\t\t * @protected\n\t\t * @member {String} #placeholder\n\t\t */\n\t\tthis.placeholder = 'data:image/svg+xml;utf8,' + encodeURIComponent( uploadingPlaceholder );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t// Upload status change - update image's view according to that status.\n\t\tif ( editor.plugins.has( 'ImageBlockEditing' ) ) {\n\t\t\teditor.editing.downcastDispatcher.on( 'attribute:uploadStatus:imageBlock', ( ...args ) => this.uploadStatusChange( ...args ) );\n\t\t}\n\n\t\tif ( editor.plugins.has( 'ImageInlineEditing' ) ) {\n\t\t\teditor.editing.downcastDispatcher.on( 'attribute:uploadStatus:imageInline', ( ...args ) => this.uploadStatusChange( ...args ) );\n\t\t}\n\t}\n\n\t/**\n\t * This method is called each time the image `uploadStatus` attribute is changed.\n\t *\n\t * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\n\t */\n\tuploadStatusChange( evt, data, conversionApi ) {\n\t\tconst editor = this.editor;\n\t\tconst modelImage = data.item;\n\t\tconst uploadId = modelImage.getAttribute( 'uploadId' );\n\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst imageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst fileRepository = editor.plugins.get( FileRepository );\n\t\tconst status = uploadId ? data.attributeNewValue : null;\n\t\tconst placeholder = this.placeholder;\n\t\tconst viewFigure = editor.editing.mapper.toViewElement( modelImage );\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\tif ( status == 'reading' ) {\n\t\t\t// Start \"appearing\" effect and show placeholder with infinite progress bar on the top\n\t\t\t// while image is read from disk.\n\t\t\t_startAppearEffect( viewFigure, viewWriter );\n\t\t\t_showPlaceholder( imageUtils, placeholder, viewFigure, viewWriter );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Show progress bar on the top of the image when image is uploading.\n\t\tif ( status == 'uploading' ) {\n\t\t\tconst loader = fileRepository.loaders.get( uploadId );\n\n\t\t\t// Start appear effect if needed - see https://github.com/ckeditor/ckeditor5-image/issues/191.\n\t\t\t_startAppearEffect( viewFigure, viewWriter );\n\n\t\t\tif ( !loader ) {\n\t\t\t\t// There is no loader associated with uploadId - this means that image came from external changes.\n\t\t\t\t// In such cases we still want to show the placeholder until image is fully uploaded.\n\t\t\t\t// Show placeholder if needed - see https://github.com/ckeditor/ckeditor5-image/issues/191.\n\t\t\t\t_showPlaceholder( imageUtils, placeholder, viewFigure, viewWriter );\n\t\t\t} else {\n\t\t\t\t// Hide placeholder and initialize progress bar showing upload progress.\n\t\t\t\t_hidePlaceholder( viewFigure, viewWriter );\n\t\t\t\t_showProgressBar( viewFigure, viewWriter, loader, editor.editing.view );\n\t\t\t\t_displayLocalImage( imageUtils, viewFigure, viewWriter, loader );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tif ( status == 'complete' && fileRepository.loaders.get( uploadId ) ) {\n\t\t\t_showCompleteIcon( viewFigure, viewWriter, editor.editing.view );\n\t\t}\n\n\t\t// Clean up.\n\t\t_hideProgressBar( viewFigure, viewWriter );\n\t\t_hidePlaceholder( viewFigure, viewWriter );\n\t\t_stopAppearEffect( viewFigure, viewWriter );\n\t}\n}\n\n// Adds ck-appear class to the image figure if one is not already applied.\n//\n// @param {module:engine/view/containerelement~ContainerElement} viewFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\nfunction _startAppearEffect( viewFigure, writer ) {\n\tif ( !viewFigure.hasClass( 'ck-appear' ) ) {\n\t\twriter.addClass( 'ck-appear', viewFigure );\n\t}\n}\n\n// Removes ck-appear class to the image figure if one is not already removed.\n//\n// @param {module:engine/view/containerelement~ContainerElement} viewFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\nfunction _stopAppearEffect( viewFigure, writer ) {\n\twriter.removeClass( 'ck-appear', viewFigure );\n}\n\n// Shows placeholder together with infinite progress bar on given image figure.\n//\n// @param {module:image/imageutils~ImageUtils} imageUtils\n// @param {String} Data-uri with a svg placeholder.\n// @param {module:engine/view/containerelement~ContainerElement} viewFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\nfunction _showPlaceholder( imageUtils, placeholder, viewFigure, writer ) {\n\tif ( !viewFigure.hasClass( 'ck-image-upload-placeholder' ) ) {\n\t\twriter.addClass( 'ck-image-upload-placeholder', viewFigure );\n\t}\n\n\tconst viewImg = imageUtils.findViewImgElement( viewFigure );\n\n\tif ( viewImg.getAttribute( 'src' ) !== placeholder ) {\n\t\twriter.setAttribute( 'src', placeholder, viewImg );\n\t}\n\n\tif ( !_getUIElement( viewFigure, 'placeholder' ) ) {\n\t\twriter.insert( writer.createPositionAfter( viewImg ), _createPlaceholder( writer ) );\n\t}\n}\n\n// Removes placeholder together with infinite progress bar on given image figure.\n//\n// @param {module:engine/view/containerelement~ContainerElement} viewFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\nfunction _hidePlaceholder( viewFigure, writer ) {\n\tif ( viewFigure.hasClass( 'ck-image-upload-placeholder' ) ) {\n\t\twriter.removeClass( 'ck-image-upload-placeholder', viewFigure );\n\t}\n\n\t_removeUIElement( viewFigure, writer, 'placeholder' );\n}\n\n// Shows progress bar displaying upload progress.\n// Attaches it to the file loader to update when upload percentace is changed.\n//\n// @param {module:engine/view/containerelement~ContainerElement} viewFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @param {module:upload/filerepository~FileLoader} loader\n// @param {module:engine/view/view~View} view\nfunction _showProgressBar( viewFigure, writer, loader, view ) {\n\tconst progressBar = _createProgressBar( writer );\n\twriter.insert( writer.createPositionAt( viewFigure, 'end' ), progressBar );\n\n\t// Update progress bar width when uploadedPercent is changed.\n\tloader.on( 'change:uploadedPercent', ( evt, name, value ) => {\n\t\tview.change( writer => {\n\t\t\twriter.setStyle( 'width', value + '%', progressBar );\n\t\t} );\n\t} );\n}\n\n// Hides upload progress bar.\n//\n// @param {module:engine/view/containerelement~ContainerElement} viewFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\nfunction _hideProgressBar( viewFigure, writer ) {\n\t_removeUIElement( viewFigure, writer, 'progressBar' );\n}\n\n// Shows complete icon and hides after a certain amount of time.\n//\n// @param {module:engine/view/containerelement~ContainerElement} viewFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @param {module:engine/view/view~View} view\nfunction _showCompleteIcon( viewFigure, writer, view ) {\n\tconst completeIcon = writer.createUIElement( 'div', { class: 'ck-image-upload-complete-icon' } );\n\n\twriter.insert( writer.createPositionAt( viewFigure, 'end' ), completeIcon );\n\n\tsetTimeout( () => {\n\t\tview.change( writer => writer.remove( writer.createRangeOn( completeIcon ) ) );\n\t}, 3000 );\n}\n\n// Create progress bar element using {@link module:engine/view/uielement~UIElement}.\n//\n// @private\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @returns {module:engine/view/uielement~UIElement}\nfunction _createProgressBar( writer ) {\n\tconst progressBar = writer.createUIElement( 'div', { class: 'ck-progress-bar' } );\n\n\twriter.setCustomProperty( 'progressBar', true, progressBar );\n\n\treturn progressBar;\n}\n\n// Create placeholder element using {@link module:engine/view/uielement~UIElement}.\n//\n// @private\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @returns {module:engine/view/uielement~UIElement}\nfunction _createPlaceholder( writer ) {\n\tconst placeholder = writer.createUIElement( 'div', { class: 'ck-upload-placeholder-loader' } );\n\n\twriter.setCustomProperty( 'placeholder', true, placeholder );\n\n\treturn placeholder;\n}\n\n// Returns {@link module:engine/view/uielement~UIElement} of given unique property from image figure element.\n// Returns `undefined` if element is not found.\n//\n// @private\n// @param {module:engine/view/element~Element} imageFigure\n// @param {String} uniqueProperty\n// @returns {module:engine/view/uielement~UIElement|undefined}\nfunction _getUIElement( imageFigure, uniqueProperty ) {\n\tfor ( const child of imageFigure.getChildren() ) {\n\t\tif ( child.getCustomProperty( uniqueProperty ) ) {\n\t\t\treturn child;\n\t\t}\n\t}\n}\n\n// Removes {@link module:engine/view/uielement~UIElement} of given unique property from image figure element.\n//\n// @private\n// @param {module:engine/view/element~Element} imageFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @param {String} uniqueProperty\nfunction _removeUIElement( viewFigure, writer, uniqueProperty ) {\n\tconst element = _getUIElement( viewFigure, uniqueProperty );\n\n\tif ( element ) {\n\t\twriter.remove( writer.createRangeOn( element ) );\n\t}\n}\n\n// Displays local data from file loader.\n//\n// @param {module:image/imageutils~ImageUtils} imageUtils\n// @param {module:engine/view/element~Element} imageFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @param {module:upload/filerepository~FileLoader} loader\nfunction _displayLocalImage( imageUtils, viewFigure, writer, loader ) {\n\tif ( loader.data ) {\n\t\tconst viewImg = imageUtils.findViewImgElement( viewFigure );\n\n\t\twriter.setAttribute( 'src', loader.data, viewImg );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageupload/imageuploadediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\n\nimport { UpcastWriter } from 'ckeditor5/src/engine';\n\nimport { Notification } from 'ckeditor5/src/ui';\nimport { ClipboardPipeline } from 'ckeditor5/src/clipboard';\nimport { FileRepository } from 'ckeditor5/src/upload';\nimport { env } from 'ckeditor5/src/utils';\n\nimport ImageUtils from '../imageutils';\nimport UploadImageCommand from './uploadimagecommand';\nimport { fetchLocalImage, isLocalImage } from '../../src/imageupload/utils';\nimport { createImageTypeRegExp } from './utils';\n\n/**\n * The editing part of the image upload feature. It registers the `'uploadImage'` command\n * and the `imageUpload` command as an aliased name.\n *\n * When an image is uploaded, it fires the {@link ~ImageUploadEditing#event:uploadComplete `uploadComplete`} event\n * that allows adding custom attributes to the {@link module:engine/model/element~Element image element}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageUploadEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ FileRepository, Notification, ClipboardPipeline, ImageUtils ];\n\t}\n\n\tstatic get pluginName() {\n\t\treturn 'ImageUploadEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'image', {\n\t\t\tupload: {\n\t\t\t\ttypes: [ 'jpeg', 'png', 'gif', 'bmp', 'webp', 'tiff' ]\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * An internal mapping of {@link module:upload/filerepository~FileLoader#id file loader UIDs} and\n\t\t * model elements during the upload.\n\t\t *\n\t\t * Model element of the uploaded image can change, for instance, when {@link module:image/image/imagetypecommand~ImageTypeCommand}\n\t\t * is executed as a result of adding caption or changing image style. As a result, the upload logic must keep track of the model\n\t\t * element (reference) and resolve the upload for the correct model element (instead of the one that landed in the `$graveyard`\n\t\t * after image type changed).\n\t\t *\n\t\t * @private\n\t\t * @readonly\n\t\t * @member {Map.}\n\t\t */\n\t\tthis._uploadImageElements = new Map();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst doc = editor.model.document;\n\t\tconst conversion = editor.conversion;\n\t\tconst fileRepository = editor.plugins.get( FileRepository );\n\t\tconst imageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst imageTypes = createImageTypeRegExp( editor.config.get( 'image.upload.types' ) );\n\t\tconst uploadImageCommand = new UploadImageCommand( editor );\n\n\t\t// Register `uploadImage` command and add `imageUpload` command as an alias for backward compatibility.\n\t\teditor.commands.add( 'uploadImage', uploadImageCommand );\n\t\teditor.commands.add( 'imageUpload', uploadImageCommand );\n\n\t\t// Register upcast converter for uploadId.\n\t\tconversion.for( 'upcast' )\n\t\t\t.attributeToAttribute( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'img',\n\t\t\t\t\tkey: 'uploadId'\n\t\t\t\t},\n\t\t\t\tmodel: 'uploadId'\n\t\t\t} );\n\n\t\t// Handle pasted images.\n\t\t// For every image file, a new file loader is created and a placeholder image is\n\t\t// inserted into the content. Then, those images are uploaded once they appear in the model\n\t\t// (see Document#change listener below).\n\t\tthis.listenTo( editor.editing.view.document, 'clipboardInput', ( evt, data ) => {\n\t\t\t// Skip if non empty HTML data is included.\n\t\t\t// https://github.com/ckeditor/ckeditor5-upload/issues/68\n\t\t\tif ( isHtmlIncluded( data.dataTransfer ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst images = Array.from( data.dataTransfer.files ).filter( file => {\n\t\t\t\t// See https://github.com/ckeditor/ckeditor5-image/pull/254.\n\t\t\t\tif ( !file ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn imageTypes.test( file.type );\n\t\t\t} );\n\n\t\t\tif ( !images.length ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tevt.stop();\n\n\t\t\teditor.model.change( writer => {\n\t\t\t\t// Set selection to paste target.\n\t\t\t\tif ( data.targetRanges ) {\n\t\t\t\t\twriter.setSelection( data.targetRanges.map( viewRange => editor.editing.mapper.toModelRange( viewRange ) ) );\n\t\t\t\t}\n\n\t\t\t\t// Upload images after the selection has changed in order to ensure the command's state is refreshed.\n\t\t\t\teditor.model.enqueueChange( 'default', () => {\n\t\t\t\t\teditor.execute( 'uploadImage', { file: images } );\n\t\t\t\t} );\n\t\t\t} );\n\t\t} );\n\n\t\t// Handle HTML pasted with images with base64 or blob sources.\n\t\t// For every image file, a new file loader is created and a placeholder image is\n\t\t// inserted into the content. Then, those images are uploaded once they appear in the model\n\t\t// (see Document#change listener below).\n\t\tthis.listenTo( editor.plugins.get( 'ClipboardPipeline' ), 'inputTransformation', ( evt, data ) => {\n\t\t\tconst fetchableImages = Array.from( editor.editing.view.createRangeIn( data.content ) )\n\t\t\t\t.filter( value => isLocalImage( imageUtils, value.item ) && !value.item.getAttribute( 'uploadProcessed' ) )\n\t\t\t\t.map( value => { return { promise: fetchLocalImage( value.item ), imageElement: value.item }; } );\n\n\t\t\tif ( !fetchableImages.length ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst writer = new UpcastWriter( editor.editing.view.document );\n\n\t\t\tfor ( const fetchableImage of fetchableImages ) {\n\t\t\t\t// Set attribute marking that the image was processed already.\n\t\t\t\twriter.setAttribute( 'uploadProcessed', true, fetchableImage.imageElement );\n\n\t\t\t\tconst loader = fileRepository.createLoader( fetchableImage.promise );\n\n\t\t\t\tif ( loader ) {\n\t\t\t\t\twriter.setAttribute( 'src', '', fetchableImage.imageElement );\n\t\t\t\t\twriter.setAttribute( 'uploadId', loader.id, fetchableImage.imageElement );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Prevents from the browser redirecting to the dropped image.\n\t\teditor.editing.view.document.on( 'dragover', ( evt, data ) => {\n\t\t\tdata.preventDefault();\n\t\t} );\n\n\t\t// Upload placeholder images that appeared in the model.\n\t\tdoc.on( 'change', () => {\n\t\t\t// Note: Reversing changes to start with insertions and only then handle removals. If it was the other way around,\n\t\t\t// loaders for **all** images that land in the $graveyard would abort while in fact only those that were **not** replaced\n\t\t\t// by other images should be aborted.\n\t\t\tconst changes = doc.differ.getChanges( { includeChangesInGraveyard: true } ).reverse();\n\t\t\tconst insertedImagesIds = new Set();\n\n\t\t\tfor ( const entry of changes ) {\n\t\t\t\tif ( entry.type == 'insert' && entry.name != '$text' ) {\n\t\t\t\t\tconst item = entry.position.nodeAfter;\n\t\t\t\t\tconst isInsertedInGraveyard = entry.position.root.rootName == '$graveyard';\n\n\t\t\t\t\tfor ( const imageElement of getImagesFromChangeItem( editor, item ) ) {\n\t\t\t\t\t\t// Check if the image element still has upload id.\n\t\t\t\t\t\tconst uploadId = imageElement.getAttribute( 'uploadId' );\n\n\t\t\t\t\t\tif ( !uploadId ) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Check if the image is loaded on this client.\n\t\t\t\t\t\tconst loader = fileRepository.loaders.get( uploadId );\n\n\t\t\t\t\t\tif ( !loader ) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( isInsertedInGraveyard ) {\n\t\t\t\t\t\t\t// If the image was inserted to the graveyard for good (**not** replaced by another image),\n\t\t\t\t\t\t\t// only then abort the loading process.\n\t\t\t\t\t\t\tif ( !insertedImagesIds.has( uploadId ) ) {\n\t\t\t\t\t\t\t\tloader.abort();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Remember the upload id of the inserted image. If it acted as a replacement for another\n\t\t\t\t\t\t\t// image (which landed in the $graveyard), the related loader will not be aborted because\n\t\t\t\t\t\t\t// this is still the same image upload.\n\t\t\t\t\t\t\tinsertedImagesIds.add( uploadId );\n\n\t\t\t\t\t\t\t// Keep the mapping between the upload ID and the image model element so the upload\n\t\t\t\t\t\t\t// can later resolve in the context of the correct model element. The model element could\n\t\t\t\t\t\t\t// change for the same upload if one image was replaced by another (e.g. image type was changed),\n\t\t\t\t\t\t\t// so this may also replace an existing mapping.\n\t\t\t\t\t\t\tthis._uploadImageElements.set( uploadId, imageElement );\n\n\t\t\t\t\t\t\tif ( loader.status == 'idle' ) {\n\t\t\t\t\t\t\t\t// If the image was inserted into content and has not been loaded yet, start loading it.\n\t\t\t\t\t\t\t\tthis._readAndUpload( loader );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Set the default handler for feeding the image element with `src` and `srcset` attributes.\n\t\tthis.on( 'uploadComplete', ( evt, { imageElement, data } ) => {\n\t\t\tconst urls = data.urls ? data.urls : data;\n\n\t\t\tthis.editor.model.change( writer => {\n\t\t\t\twriter.setAttribute( 'src', urls.default, imageElement );\n\t\t\t\tthis._parseAndSetSrcsetAttributeOnImage( urls, imageElement, writer );\n\t\t\t} );\n\t\t}, { priority: 'low' } );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tconst schema = this.editor.model.schema;\n\n\t\t// Setup schema to allow uploadId and uploadStatus for images.\n\t\t// Wait for ImageBlockEditing or ImageInlineEditing to register their elements first,\n\t\t// that's why doing this in afterInit() instead of init().\n\t\tif ( this.editor.plugins.has( 'ImageBlockEditing' ) ) {\n\t\t\tschema.extend( 'imageBlock', {\n\t\t\t\tallowAttributes: [ 'uploadId', 'uploadStatus' ]\n\t\t\t} );\n\t\t}\n\n\t\tif ( this.editor.plugins.has( 'ImageInlineEditing' ) ) {\n\t\t\tschema.extend( 'imageInline', {\n\t\t\t\tallowAttributes: [ 'uploadId', 'uploadStatus' ]\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Reads and uploads an image.\n\t *\n\t * The image is read from the disk and as a Base64-encoded string it is set temporarily to\n\t * `image[src]`. When the image is successfully uploaded, the temporary data is replaced with the target\n\t * image's URL (the URL to the uploaded image on the server).\n\t *\n\t * @protected\n\t * @param {module:upload/filerepository~FileLoader} loader\n\t * @returns {Promise}\n\t */\n\t_readAndUpload( loader ) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst t = editor.locale.t;\n\t\tconst fileRepository = editor.plugins.get( FileRepository );\n\t\tconst notification = editor.plugins.get( Notification );\n\t\tconst imageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst imageUploadElements = this._uploadImageElements;\n\n\t\tmodel.enqueueChange( 'transparent', writer => {\n\t\t\twriter.setAttribute( 'uploadStatus', 'reading', imageUploadElements.get( loader.id ) );\n\t\t} );\n\n\t\treturn loader.read()\n\t\t\t.then( () => {\n\t\t\t\tconst promise = loader.upload();\n\t\t\t\tconst imageElement = imageUploadElements.get( loader.id );\n\n\t\t\t\t// Force reā€“paint in Safari. Without it, the image will display with a wrong size.\n\t\t\t\t// https://github.com/ckeditor/ckeditor5/issues/1975\n\t\t\t\t/* istanbul ignore next */\n\t\t\t\tif ( env.isSafari ) {\n\t\t\t\t\tconst viewFigure = editor.editing.mapper.toViewElement( imageElement );\n\t\t\t\t\tconst viewImg = imageUtils.findViewImgElement( viewFigure );\n\n\t\t\t\t\teditor.editing.view.once( 'render', () => {\n\t\t\t\t\t\t// Early returns just to be safe. There might be some code ran\n\t\t\t\t\t\t// in between the outer scope and this callback.\n\t\t\t\t\t\tif ( !viewImg.parent ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst domFigure = editor.editing.view.domConverter.mapViewToDom( viewImg.parent );\n\n\t\t\t\t\t\tif ( !domFigure ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst originalDisplay = domFigure.style.display;\n\n\t\t\t\t\t\tdomFigure.style.display = 'none';\n\n\t\t\t\t\t\t// Make sure this line will never be removed during minification for having \"no effect\".\n\t\t\t\t\t\tdomFigure._ckHack = domFigure.offsetHeight;\n\n\t\t\t\t\t\tdomFigure.style.display = originalDisplay;\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\tmodel.enqueueChange( 'transparent', writer => {\n\t\t\t\t\twriter.setAttribute( 'uploadStatus', 'uploading', imageElement );\n\t\t\t\t} );\n\n\t\t\t\treturn promise;\n\t\t\t} )\n\t\t\t.then( data => {\n\t\t\t\tmodel.enqueueChange( 'transparent', writer => {\n\t\t\t\t\tconst imageElement = imageUploadElements.get( loader.id );\n\n\t\t\t\t\twriter.setAttribute( 'uploadStatus', 'complete', imageElement );\n\n\t\t\t\t\t/**\n\t\t\t\t\t * An event fired when an image is uploaded. You can hook into this event to provide\n\t\t\t\t\t * custom attributes to the {@link module:engine/model/element~Element image element} based on the data from\n\t\t\t\t\t * the server.\n\t\t\t\t\t *\n\t\t\t\t\t * \t\tconst imageUploadEditing = editor.plugins.get( 'ImageUploadEditing' );\n\t\t\t\t\t *\n\t\t\t\t\t * \t\timageUploadEditing.on( 'uploadComplete', ( evt, { data, imageElement } ) => {\n\t\t\t\t\t * \t\t\teditor.model.change( writer => {\n\t\t\t\t\t * \t\t\t\twriter.setAttribute( 'someAttribute', 'foo', imageElement );\n\t\t\t\t\t * \t\t\t} );\n\t\t\t\t\t * \t\t} );\n\t\t\t\t\t *\n\t\t\t\t\t * You can also stop the default handler that sets the `src` and `srcset` attributes\n\t\t\t\t\t * if you want to provide custom values for these attributes.\n\t\t\t\t\t *\n\t\t\t\t\t * \t\timageUploadEditing.on( 'uploadComplete', ( evt, { data, imageElement } ) => {\n\t\t\t\t\t * \t\t\tevt.stop();\n\t\t\t\t\t * \t\t} );\n\t\t\t\t\t *\n\t\t\t\t\t * **Note**: This event is fired by the {@link module:image/imageupload/imageuploadediting~ImageUploadEditing} plugin.\n\t\t\t\t\t *\n\t\t\t\t\t * @event uploadComplete\n\t\t\t\t\t * @param {Object} data The `uploadComplete` event data.\n\t\t\t\t\t * @param {Object} data.data The data coming from the upload adapter.\n\t\t\t\t\t * @param {module:engine/model/element~Element} data.imageElement The\n\t\t\t\t\t * model {@link module:engine/model/element~Element image element} that can be customized.\n\t\t\t\t\t */\n\t\t\t\t\tthis.fire( 'uploadComplete', { data, imageElement } );\n\t\t\t\t} );\n\n\t\t\t\tclean();\n\t\t\t} )\n\t\t\t.catch( error => {\n\t\t\t\t// If status is not 'error' nor 'aborted' - throw error because it means that something else went wrong,\n\t\t\t\t// it might be generic error and it would be real pain to find what is going on.\n\t\t\t\tif ( loader.status !== 'error' && loader.status !== 'aborted' ) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\n\t\t\t\t// Might be 'aborted'.\n\t\t\t\tif ( loader.status == 'error' && error ) {\n\t\t\t\t\tnotification.showWarning( error, {\n\t\t\t\t\t\ttitle: t( 'Upload failed' ),\n\t\t\t\t\t\tnamespace: 'upload'\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\t// Permanently remove image from insertion batch.\n\t\t\t\tmodel.enqueueChange( 'transparent', writer => {\n\t\t\t\t\twriter.remove( imageUploadElements.get( loader.id ) );\n\t\t\t\t} );\n\n\t\t\t\tclean();\n\t\t\t} );\n\n\t\tfunction clean() {\n\t\t\tmodel.enqueueChange( 'transparent', writer => {\n\t\t\t\tconst imageElement = imageUploadElements.get( loader.id );\n\n\t\t\t\twriter.removeAttribute( 'uploadId', imageElement );\n\t\t\t\twriter.removeAttribute( 'uploadStatus', imageElement );\n\n\t\t\t\timageUploadElements.delete( loader.id );\n\t\t\t} );\n\n\t\t\tfileRepository.destroyLoader( loader );\n\t\t}\n\t}\n\n\t/**\n\t * Creates the `srcset` attribute based on a given file upload response and sets it as an attribute to a specific image element.\n\t *\n\t * @protected\n\t * @param {Object} data Data object from which `srcset` will be created.\n\t * @param {module:engine/model/element~Element} image The image element on which the `srcset` attribute will be set.\n\t * @param {module:engine/model/writer~Writer} writer\n\t */\n\t_parseAndSetSrcsetAttributeOnImage( data, image, writer ) {\n\t\t// Srcset attribute for responsive images support.\n\t\tlet maxWidth = 0;\n\n\t\tconst srcsetAttribute = Object.keys( data )\n\t\t\t// Filter out keys that are not integers.\n\t\t\t.filter( key => {\n\t\t\t\tconst width = parseInt( key, 10 );\n\n\t\t\t\tif ( !isNaN( width ) ) {\n\t\t\t\t\tmaxWidth = Math.max( maxWidth, width );\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} )\n\n\t\t\t// Convert each key to srcset entry.\n\t\t\t.map( key => `${ data[ key ] } ${ key }w` )\n\n\t\t\t// Join all entries.\n\t\t\t.join( ', ' );\n\n\t\tif ( srcsetAttribute != '' ) {\n\t\t\twriter.setAttribute( 'srcset', {\n\t\t\t\tdata: srcsetAttribute,\n\t\t\t\twidth: maxWidth\n\t\t\t}, image );\n\t\t}\n\t}\n}\n\n// Returns `true` if non-empty `text/html` is included in the data transfer.\n//\n// @param {module:clipboard/datatransfer~DataTransfer} dataTransfer\n// @returns {Boolean}\nexport function isHtmlIncluded( dataTransfer ) {\n\treturn Array.from( dataTransfer.types ).includes( 'text/html' ) && dataTransfer.getData( 'text/html' ) !== '';\n}\n\nfunction getImagesFromChangeItem( editor, item ) {\n\tconst imageUtils = editor.plugins.get( 'ImageUtils' );\n\n\treturn Array.from( editor.model.createRangeOn( item ) )\n\t\t.filter( value => imageUtils.isImage( value.item ) )\n\t\t.map( value => value.item );\n}\n","/**\n * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageupload\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport ImageUploadUI from './imageupload/imageuploadui';\nimport ImageUploadProgress from './imageupload/imageuploadprogress';\nimport ImageUploadEditing from './imageupload/imageuploadediting';\n\n/**\n * The image upload plugin.\n *\n * For a detailed overview, check the {@glink features/images/image-upload/image-upload image upload feature} documentation.\n *\n * This plugin does not do anything directly, but it loads a set of specific plugins to enable image uploading:\n *\n * * {@link module:image/imageupload/imageuploadediting~ImageUploadEditing},\n * * {@link module:image/imageupload/imageuploadui~ImageUploadUI},\n * * {@link module:image/imageupload/imageuploadprogress~ImageUploadProgress}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageUpload extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageUpload';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ImageUploadEditing, ImageUploadUI, ImageUploadProgress ];\n\t}\n}\n\n/**\n * The image upload configuration.\n *\n * @member {module:image/imageupload~ImageUploadConfig} module:image/image~ImageConfig#upload\n */\n\n/**\n * The configuration of the image upload feature. Used by the image upload feature in the `@ckeditor/ckeditor5-image` package.\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n * \t\t\t\timage: {\n * \t\t\t\t\tupload: ... // Image upload feature options.\n * \t\t\t\t}\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.\n *\n * @interface module:image/imageupload~ImageUploadConfig\n */\n\n/**\n * The list of accepted image types.\n *\n * The accepted types of images can be customized to allow only certain types of images:\n *\n *\t\t// Allow only JPEG and PNG images:\n *\t\tconst imageUploadConfig = {\n *\t\t\ttypes: [ 'png', 'jpeg' ]\n *\t\t};\n *\n * The type string should match [one of the sub-types](https://www.iana.org/assignments/media-types/media-types.xhtml#image)\n * of the image MIME type. For example, for the `image/jpeg` MIME type, add `'jpeg'` to your image upload configuration.\n *\n * **Note:** This setting only restricts some image types to be selected and uploaded through the CKEditor UI and commands. Image type\n * recognition and filtering should also be implemented on the server which accepts image uploads.\n *\n * @member {Array.} module:image/imageupload~ImageUploadConfig#types\n * @default [ 'jpeg', 'png', 'gif', 'bmp', 'webp', 'tiff' ]\n */\n"],"sourceRoot":""}