{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imageupload/utils.js","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/uploadimagecommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imageupload/imageuploadediting.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imageupload.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imageinsert/ui/imageinsertformrowview.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imageinsert/ui/imageinsertpanelview.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imageinsert/utils.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imageinsert/imageinsertui.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imageinsert.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/theme/icons/image_placeholder.svg","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/image/imageloadobserver.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/image/converters.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/image/insertimagecommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/image/imageediting.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/imagetextalternativecommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/imagetextalternativeediting.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/ui/textalternativeformview.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/image/ui/utils.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/imagetextalternativeui.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/image.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/image/utils.js"],"names":["createImageTypeRegExp","types","regExpSafeNames","map","type","replace","RegExp","join","fetchLocalImage","image","Promise","resolve","reject","imageSrc","getAttribute","fetch","then","resource","blob","mimeType","getImageMimeType","ext","filename","file","File","catch","err","name","convertLocalImageOnCanvas","isLocalImage","node","is","match","src","toLowerCase","getBlobFromCanvas","global","document","createElement","addEventListener","canvas","width","height","ctx","getContext","drawImage","toBlob","ImageUploadUI","editor","this","t","componentCreator","locale","view","FileDialogButtonView","command","commands","get","imageTypes","config","imageTypesRegExp","set","acceptedType","allowMultipleFiles","buttonView","label","icon","icons","tooltip","bind","to","on","evt","files","imagesToUpload","Array","from","filter","test","length","execute","ui","componentFactory","add","Plugin","ImageUploadProgress","placeholder","encodeURIComponent","uploadingPlaceholder","editing","downcastDispatcher","uploadStatusChange","data","conversionApi","modelImage","item","uploadId","consumable","consume","fileRepository","plugins","FileRepository","status","attributeNewValue","viewFigure","mapper","toViewElement","viewWriter","writer","_startAppearEffect","_showPlaceholder","loader","loaders","_hidePlaceholder","_showProgressBar","_displayLocalImage","_showCompleteIcon","_hideProgressBar","_stopAppearEffect","hasClass","addClass","removeClass","viewImg","getViewImgFromWidget","setAttribute","_getUIElement","insert","createPositionAfter","_createPlaceholder","_removeUIElement","progressBar","_createProgressBar","createPositionAt","value","change","setStyle","completeIcon","createUIElement","class","setTimeout","remove","createRangeOn","setCustomProperty","imageFigure","uniqueProperty","getChildren","child","getCustomProperty","element","UploadImageCommand","imageElement","model","selection","getSelectedElement","isImage","isEnabled","isImageAllowed","options","toArray","uploadImage","Command","createLoader","insertImage","id","ImageUploadEditing","define","upload","Notification","Clipboard","doc","schema","conversion","extend","allowAttributes","uploadImageCommand","for","attributeToAttribute","key","listenTo","isHtmlIncluded","dataTransfer","images","ranges","targetRanges","viewRange","toModelRange","setSelection","stop","enqueueChange","fetchableImages","createRangeIn","content","promise","UpcastWriter","fetchableImage","preventDefault","changes","differ","getChanges","includeChangesInGraveyard","entry","position","nodeAfter","isInGraveyard","root","rootName","getImagesFromChangeItem","abort","_readAndUpload","notification","read","env","isSafari","once","parent","domFigure","domConverter","mapViewToDom","originalDisplay","style","display","_ckHack","offsetHeight","setAttributes","uploadStatus","default","_parseAndSetSrcsetAttributeOnImage","clean","error","showWarning","title","namespace","removeAttribute","destroyLoader","maxWidth","srcsetAttribute","Object","keys","parseInt","isNaN","Math","max","includes","getData","ImageUpload","ImageUploadFormRowView","bindTemplate","children","createCollection","forEach","labelView","_role","_ariaLabelledBy","setTemplate","tag","attributes","role","View","ImageInsertPanelView","integrations","_createActionButtons","insertButtonView","cancelButtonView","dropdownView","_createDropdownView","focusTracker","FocusTracker","keystrokes","KeystrokeHandler","_focusables","ViewCollection","_focusCycler","FocusCycler","focusables","keystrokeHandler","actions","focusPrevious","focusNext","Collection","integration","integrationView","fieldView","imageURLInputValue","trim","_integrations","entries","tabindex","ImageInsertFormRowView","submitHandler","childViews","v","stopPropagation","domEvt","priority","find","createDropdown","SplitButtonView","splitButtonView","panelView","extendTemplate","ButtonView","check","withText","cancel","delegate","focusFirst","prepareIntegrations","panelItems","imageInsertUIPlugin","PREDEFINED_INTEGRATIONS","createLabeledInputView","has","ckFinderButton","create","openCKFinder","reduce","object","labeledInputView","LabeledFieldView","createLabeledInputText","ImageInsertUI","imageInsertView","actionView","_setUpDropdown","insertImageViaUrlForm","getIntegration","onSubmit","selectedElement","source","closePanel","focus","isOpen","ImageInsert","module","exports","ImageLoadObserver","domRoot","event","domEvent","domElement","target","checkShouldIgnoreEventFromTarget","tagName","_fireEvents","useCapture","fire","Observer","viewFigureToModel","dispatcher","converter","viewItem","classes","viewImage","hasAttribute","conversionResult","convertItem","modelCursor","first","modelRange","getItems","convertChildren","updateConversionResult","srcsetAttributeConverter","figure","img","srcset","attributeOldValue","modelToViewAttributeConverter","attributeKey","InsertImageCommand","ImageEditing","addObserver","register","isObject","isBlock","allowWhere","elementToElement","modelElement","createImageViewElement","toImageWidget","insertImageCommand","emptyElement","createEmptyElement","createContainerElement","ImageTextAlternativeCommand","newValue","ImageTextAlternativeEditing","TextAlternativeFormView","labeledInput","_createLabeledInputView","saveButtonView","_createButton","injectCssTransitionDisabler","className","eventName","button","repositionContextualBalloon","balloon","getSelectedImageWidget","getBalloonPositionData","updatePosition","editingView","defaultPositions","BalloonPanelView","viewToDom","positions","northArrowSouth","northArrowSouthWest","northArrowSouthEast","southArrowNorth","southArrowNorthWest","southArrowNorthEast","ImageTextAlternativeUI","_createForm","_form","destroy","lowVision","_showForm","viewDocument","_balloon","render","_hideForm","_isVisible","clickOutsideHandler","emitter","activator","contextElements","callback","disableCssTransitions","_isInBalloon","select","enableCssTransitions","focusEditable","isFocused","visibleView","hasView","ContextualBalloon","ImageTextAlternative","Image","viewElement","isImageWidget","Widget","toWidget","labelCreator","imgElement","altText","isWidget","insertPosition","insertAtSelection","findOptimalInsertionPosition","insertContent","isImageAllowedInParent","checkSelectionOnObject","isInOtherImage","figureView","figureChildren","figureChild","push","viewChild","getInsertImageParent","checkChild","getAncestors","every","ancestor","insertAt","isEmpty"],"mappings":"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","file":"js/chunk-vendors~1e9611b1.307d8256.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/utils\n */\n\n/* global fetch, File */\n\nimport { global } from 'ckeditor5/src/utils';\n\n/**\n * Creates a regular expression used to test for image files.\n *\n *\t\tconst imageType = createImageTypeRegExp( [ 'png', 'jpeg', 'svg+xml', 'vnd.microsoft.icon' ] );\n *\n *\t\tconsole.log( 'is supported image', imageType.test( file.type ) );\n *\n * @param {Array.} types\n * @returns {RegExp}\n */\nexport function createImageTypeRegExp( types ) {\n\t// Sanitize the MIME type name which may include: \"+\", \"-\" or \".\".\n\tconst regExpSafeNames = types.map( type => type.replace( '+', '\\\\+' ) );\n\n\treturn new RegExp( `^image\\\\/(${ regExpSafeNames.join( '|' ) })$` );\n}\n\n/**\n * Creates a promise that fetches the image local source (Base64 or blob) and resolves with a `File` object.\n *\n * @param {module:engine/view/element~Element} image Image whose source to fetch.\n * @returns {Promise.} A promise which resolves when an image source is fetched and converted to a `File` instance.\n * It resolves with a `File` object. If there were any errors during file processing, the promise will be rejected.\n */\nexport function fetchLocalImage( image ) {\n\treturn new Promise( ( resolve, reject ) => {\n\t\tconst imageSrc = image.getAttribute( 'src' );\n\n\t\t// Fetch works asynchronously and so does not block browser UI when processing data.\n\t\tfetch( imageSrc )\n\t\t\t.then( resource => resource.blob() )\n\t\t\t.then( blob => {\n\t\t\t\tconst mimeType = getImageMimeType( blob, imageSrc );\n\t\t\t\tconst ext = mimeType.replace( 'image/', '' );\n\t\t\t\tconst filename = `image.${ ext }`;\n\t\t\t\tconst file = new File( [ blob ], filename, { type: mimeType } );\n\n\t\t\t\tresolve( file );\n\t\t\t} )\n\t\t\t.catch( err => {\n\t\t\t\t// Fetch fails only, if it can't make a request due to a network failure or if anything prevented the request\n\t\t\t\t// from completing, i.e. the Content Security Policy rules. It is not possible to detect the exact cause of failure,\n\t\t\t\t// so we are just trying the fallback solution, if general TypeError is thrown.\n\t\t\t\treturn err && err.name === 'TypeError' ?\n\t\t\t\t\tconvertLocalImageOnCanvas( imageSrc ).then( resolve ).catch( reject ) :\n\t\t\t\t\treject( err );\n\t\t\t} );\n\t} );\n}\n\n/**\n * Checks whether a given node is an image element with a local source (Base64 or blob).\n *\n * @param {module:engine/view/node~Node} node The node to check.\n * @returns {Boolean}\n */\nexport function isLocalImage( node ) {\n\tif ( !node.is( 'element', 'img' ) || !node.getAttribute( 'src' ) ) {\n\t\treturn false;\n\t}\n\n\treturn node.getAttribute( 'src' ).match( /^data:image\\/\\w+;base64,/g ) ||\n\t\tnode.getAttribute( 'src' ).match( /^blob:/g );\n}\n\n// Extracts an image type based on its blob representation or its source.\n//\n// @param {String} src Image `src` attribute value.\n// @param {Blob} blob Image blob representation.\n// @returns {String}\nfunction getImageMimeType( blob, src ) {\n\tif ( blob.type ) {\n\t\treturn blob.type;\n\t} else if ( src.match( /data:(image\\/\\w+);base64/ ) ) {\n\t\treturn src.match( /data:(image\\/\\w+);base64/ )[ 1 ].toLowerCase();\n\t} else {\n\t\t// Fallback to 'jpeg' as common extension.\n\t\treturn 'image/jpeg';\n\t}\n}\n\n// Creates a promise that converts the image local source (Base64 or blob) to a blob using canvas and resolves\n// with a `File` object.\n//\n// @param {String} imageSrc Image `src` attribute value.\n// @returns {Promise.} A promise which resolves when an image source is converted to a `File` instance.\n// It resolves with a `File` object. If there were any errors during file processing, the promise will be rejected.\nfunction convertLocalImageOnCanvas( imageSrc ) {\n\treturn getBlobFromCanvas( imageSrc ).then( blob => {\n\t\tconst mimeType = getImageMimeType( blob, imageSrc );\n\t\tconst ext = mimeType.replace( 'image/', '' );\n\t\tconst filename = `image.${ ext }`;\n\n\t\treturn new File( [ blob ], filename, { type: mimeType } );\n\t} );\n}\n\n// Creates a promise that resolves with a `Blob` object converted from the image source (Base64 or blob).\n//\n// @param {String} imageSrc Image `src` attribute value.\n// @returns {Promise.}\nfunction getBlobFromCanvas( imageSrc ) {\n\treturn new Promise( ( resolve, reject ) => {\n\t\tconst image = global.document.createElement( 'img' );\n\n\t\timage.addEventListener( 'load', () => {\n\t\t\tconst canvas = global.document.createElement( 'canvas' );\n\n\t\t\tcanvas.width = image.width;\n\t\t\tcanvas.height = image.height;\n\n\t\t\tconst ctx = canvas.getContext( '2d' );\n\n\t\t\tctx.drawImage( image, 0, 0 );\n\n\t\t\tcanvas.toBlob( blob => blob ? resolve( blob ) : reject() );\n\t\t} );\n\n\t\timage.addEventListener( 'error', () => reject() );\n\n\t\timage.src = imageSrc;\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/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/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';\nimport { getViewImgFromWidget } from '../image/utils';\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\teditor.editing.downcastDispatcher.on( 'attribute:uploadStatus:image', ( ...args ) => this.uploadStatusChange( ...args ) );\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 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( 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( 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( 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 {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( 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 = getViewImgFromWidget( 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:engine/view/element~Element} imageFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @param {module:upload/filerepository~FileLoader} loader\nfunction _displayLocalImage( viewFigure, writer, loader ) {\n\tif ( loader.data ) {\n\t\tconst viewImg = getViewImgFromWidget( 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\nimport { FileRepository } from 'ckeditor5/src/upload';\nimport { Command } from 'ckeditor5/src/core';\nimport { toArray } from 'ckeditor5/src/utils';\n\nimport { insertImage, isImageAllowed } from '../image/utils';\n\n/**\n * @module image/imageupload/uploadimagecommand\n */\n\n/**\n * The upload image command.\n *\n * The command is registered by the {@link module:image/imageupload/imageuploadediting~ImageUploadEditing} plugin as `uploadImage`\n * and it is also available via aliased `imageUpload` name.\n *\n * In order to upload an image at the current selection position\n * (according to the {@link module:widget/utils~findOptimalInsertionPosition} algorithm),\n * execute the command and pass the native image file instance:\n *\n *\t\tthis.listenTo( editor.editing.view.document, 'clipboardInput', ( evt, data ) => {\n *\t\t\t// Assuming that only images were pasted:\n *\t\t\tconst images = Array.from( data.dataTransfer.files );\n *\n *\t\t\t// Upload the first image:\n *\t\t\teditor.execute( 'uploadImage', { file: images[ 0 ] } );\n *\t\t} );\n *\n * It is also possible to insert multiple images at once:\n *\n *\t\teditor.execute( 'uploadImage', {\n *\t\t\tfile: [\n *\t\t\t\tfile1,\n *\t\t\t\tfile2\n *\t\t\t]\n *\t\t} );\n *\n * @extends module:core/command~Command\n */\nexport default class UploadImageCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst imageElement = this.editor.model.document.selection.getSelectedElement();\n\t\tconst isImage = imageElement && imageElement.name === 'image' || false;\n\n\t\tthis.isEnabled = isImageAllowed( this.editor.model ) || isImage;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options Options for the executed command.\n\t * @param {File|Array.} options.file The image file or an array of image files to upload.\n\t */\n\texecute( options ) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\n\t\tconst fileRepository = editor.plugins.get( FileRepository );\n\n\t\tfor ( const file of toArray( options.file ) ) {\n\t\t\tuploadImage( model, fileRepository, file );\n\t\t}\n\t}\n}\n\n// Handles uploading single file.\n//\n// @param {module:engine/model/model~Model} model\n// @param {File} file\nfunction uploadImage( model, fileRepository, file ) {\n\tconst loader = fileRepository.createLoader( file );\n\n\t// Do not throw when upload adapter is not set. FileRepository will log an error anyway.\n\tif ( !loader ) {\n\t\treturn;\n\t}\n\n\tinsertImage( model, { uploadId: loader.id } );\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 { Clipboard } from 'ckeditor5/src/clipboard';\nimport { FileRepository } from 'ckeditor5/src/upload';\nimport { env } from 'ckeditor5/src/utils';\n\nimport UploadImageCommand from './uploadimagecommand';\nimport { fetchLocalImage, isLocalImage } from '../../src/imageupload/utils';\nimport { createImageTypeRegExp } from './utils';\nimport { getViewImgFromWidget } from '../image/utils';\n\n/**\n * The editing part of the image upload feature. It registers the `'uploadImage'` command\n * and `imageUpload` command as an aliased name.\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, Clipboard ];\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\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 schema = editor.model.schema;\n\t\tconst conversion = editor.conversion;\n\t\tconst fileRepository = editor.plugins.get( FileRepository );\n\n\t\tconst imageTypes = createImageTypeRegExp( editor.config.get( 'image.upload.types' ) );\n\n\t\t// Setup schema to allow uploadId and uploadStatus for images.\n\t\tschema.extend( 'image', {\n\t\t\tallowAttributes: [ 'uploadId', 'uploadStatus' ]\n\t\t} );\n\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\tconst ranges = data.targetRanges.map( viewRange => editor.editing.mapper.toModelRange( viewRange ) );\n\n\t\t\teditor.model.change( writer => {\n\t\t\t\t// Set selection to paste target.\n\t\t\t\twriter.setSelection( ranges );\n\n\t\t\t\tif ( images.length ) {\n\t\t\t\t\tevt.stop();\n\n\t\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\t\teditor.model.enqueueChange( 'default', () => {\n\t\t\t\t\t\teditor.execute( 'uploadImage', { file: images } );\n\t\t\t\t\t} );\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( Clipboard ), 'inputTransformation', ( evt, data ) => {\n\t\t\tconst fetchableImages = Array.from( editor.editing.view.createRangeIn( data.content ) )\n\t\t\t\t.filter( value => isLocalImage( 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\tconst changes = doc.differ.getChanges( { includeChangesInGraveyard: true } );\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 isInGraveyard = entry.position.root.rootName == '$graveyard';\n\n\t\t\t\t\tfor ( const image 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 = image.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 ( isInGraveyard ) {\n\t\t\t\t\t\t\t// If the image was inserted to the graveyard - abort the loading process.\n\t\t\t\t\t\t\tloader.abort();\n\t\t\t\t\t\t} else if ( loader.status == 'idle' ) {\n\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\tthis._readAndUpload( loader, image );\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\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 * @param {module:engine/model/element~Element} imageElement\n\t * @returns {Promise}\n\t */\n\t_readAndUpload( loader, imageElement ) {\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\n\t\tmodel.enqueueChange( 'transparent', writer => {\n\t\t\twriter.setAttribute( 'uploadStatus', 'reading', imageElement );\n\t\t} );\n\n\t\treturn loader.read()\n\t\t\t.then( () => {\n\t\t\t\tconst promise = loader.upload();\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 = getViewImgFromWidget( 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\twriter.setAttributes( { uploadStatus: 'complete', src: data.default }, imageElement );\n\t\t\t\t\tthis._parseAndSetSrcsetAttributeOnImage( data, imageElement, writer );\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\tclean();\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( imageElement );\n\t\t\t\t} );\n\t\t\t} );\n\n\t\tfunction clean() {\n\t\t\tmodel.enqueueChange( 'transparent', writer => {\n\t\t\t\twriter.removeAttribute( 'uploadId', imageElement );\n\t\t\t\twriter.removeAttribute( 'uploadStatus', imageElement );\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// 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\treturn Array.from( editor.model.createRangeOn( item ) )\n\t\t.filter( value => value.item.is( 'element', 'image' ) )\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/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","/**\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/imageinsert/ui/imageinsertformrowview\n */\n\nimport { View } from 'ckeditor5/src/ui';\n\nimport '../../../theme/imageinsertformrowview.css';\n\n/**\n * The class representing a single row in a complex form,\n * used by {@link module:image/imageinsert/ui/imageinsertpanelview~ImageInsertPanelView}.\n *\n * **Note**: For now this class is private. When more use cases appear (beyond `ckeditor5-table` and `ckeditor5-image`),\n * it will become a component in `ckeditor5-ui`.\n *\n * @private\n * @extends module:ui/view~View\n */\nexport default class ImageUploadFormRowView extends View {\n\t/**\n\t * Creates an instance of the form row class.\n\t *\n\t * @param {module:utils/locale~Locale} locale The locale instance.\n\t * @param {Object} options\n\t * @param {Array.} [options.children]\n\t * @param {String} [options.class]\n\t * @param {module:ui/view~View} [options.labelView] When passed, the row gets the `group` and `aria-labelledby`\n\t * DOM attributes and gets described by the label.\n\t */\n\tconstructor( locale, options = {} ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * An additional CSS class added to the {@link #element}.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #class\n\t\t */\n\t\tthis.set( 'class', options.class || null );\n\n\t\t/**\n\t\t * A collection of row items (buttons, dropdowns, etc.).\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.children = this.createCollection();\n\n\t\tif ( options.children ) {\n\t\t\toptions.children.forEach( child => this.children.add( child ) );\n\t\t}\n\n\t\t/**\n\t\t * The role property reflected by the `role` DOM attribute of the {@link #element}.\n\t\t *\n\t\t * **Note**: Used only when a `labelView` is passed to constructor `options`.\n\t\t *\n\t\t * @private\n\t\t * @observable\n\t\t * @member {String} #role\n\t\t */\n\t\tthis.set( '_role', null );\n\n\t\t/**\n\t\t * The ARIA property reflected by the `aria-labelledby` DOM attribute of the {@link #element}.\n\t\t *\n\t\t * **Note**: Used only when a `labelView` is passed to constructor `options`.\n\t\t *\n\t\t * @private\n\t\t * @observable\n\t\t * @member {String} #ariaLabelledBy\n\t\t */\n\t\tthis.set( '_ariaLabelledBy', null );\n\n\t\tif ( options.labelView ) {\n\t\t\tthis.set( {\n\t\t\t\t_role: 'group',\n\t\t\t\t_ariaLabelledBy: options.labelView.id\n\t\t\t} );\n\t\t}\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-form__row',\n\t\t\t\t\tbind.to( 'class' )\n\t\t\t\t],\n\t\t\t\trole: bind.to( '_role' ),\n\t\t\t\t'aria-labelledby': bind.to( '_ariaLabelledBy' )\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\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/imageinsert/ui/imageinsertpanelview\n */\n\nimport { icons } from 'ckeditor5/src/core';\nimport { ButtonView, View, SplitButtonView, ViewCollection, submitHandler, createDropdown, FocusCycler } from 'ckeditor5/src/ui';\nimport { Collection, FocusTracker, KeystrokeHandler } from 'ckeditor5/src/utils';\n\nimport ImageInsertFormRowView from './imageinsertformrowview';\n\nimport '../../../theme/imageinsert.css';\n\n/**\n * The insert an image via URL view controller class.\n *\n * See {@link module:image/imageinsert/ui/imageinsertpanelview~ImageInsertPanelView}.\n *\n * @extends module:ui/view~View\n */\nexport default class ImageInsertPanelView extends View {\n\t/**\n\t * Creates a view for the dropdown panel of {@link module:image/imageinsert/imageinsertui~ImageInsertUI}.\n\t *\n\t * @param {module:utils/locale~Locale} [locale] The localization services instance.\n\t * @param {Object} [integrations] An integrations object that contains\n\t * components (or tokens for components) to be shown in the panel view.\n\t */\n\tconstructor( locale, integrations ) {\n\t\tsuper( locale );\n\n\t\tconst { insertButtonView, cancelButtonView } = this._createActionButtons( locale );\n\n\t\t/**\n\t\t * The \"insert/update\" button view.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView}\n\t\t */\n\t\tthis.insertButtonView = insertButtonView;\n\n\t\t/**\n\t\t * The \"cancel\" button view.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView}\n\t\t */\n\t\tthis.cancelButtonView = cancelButtonView;\n\n\t\t/**\n\t\t * The dropdown view.\n\t\t *\n\t\t * @member {module:ui/dropdown/dropdownview~DropdownView}\n\t\t */\n\t\tthis.dropdownView = this._createDropdownView( locale );\n\n\t\t/**\n\t\t * The value of the URL input.\n\t\t *\n\t\t * @member {String} #imageURLInputValue\n\t\t * @observable\n\t\t */\n\t\tthis.set( 'imageURLInputValue', '' );\n\n\t\t/**\n\t\t * Tracks information about DOM focus in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker}\n\t\t */\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\t/**\n\t\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\t/**\n\t\t * A collection of views that can be focused in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis._focusables = new ViewCollection();\n\n\t\t/**\n\t\t * Helps cycling over {@link #_focusables} in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/focuscycler~FocusCycler}\n\t\t */\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate form fields backwards using the Shift + Tab keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate form fields forwards using the Tab key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * A collection of the defined integrations for inserting the images.\n\t\t *\n\t\t * @private\n\t\t * @member {module:utils/collection~Collection}\n\t\t */\n\t\tthis.set( '_integrations', new Collection() );\n\n\t\tif ( integrations ) {\n\t\t\tfor ( const [ integration, integrationView ] of Object.entries( integrations ) ) {\n\t\t\t\tif ( integration === 'insertImageViaUrl' ) {\n\t\t\t\t\tintegrationView.fieldView.bind( 'value' ).to( this, 'imageURLInputValue', value => value || '' );\n\n\t\t\t\t\tintegrationView.fieldView.on( 'input', () => {\n\t\t\t\t\t\tthis.imageURLInputValue = integrationView.fieldView.element.value.trim();\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\tintegrationView.name = integration;\n\n\t\t\t\tthis._integrations.add( integrationView );\n\t\t\t}\n\t\t}\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'form',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-image-insert-form'\n\t\t\t\t],\n\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\t...this._integrations,\n\t\t\t\tnew ImageInsertFormRowView( locale, {\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\tthis.insertButtonView,\n\t\t\t\t\t\tthis.cancelButtonView\n\t\t\t\t\t],\n\t\t\t\t\tclass: 'ck-image-insert-form__action-row'\n\t\t\t\t} )\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tsubmitHandler( {\n\t\t\tview: this\n\t\t} );\n\n\t\tconst childViews = [\n\t\t\t...this._integrations,\n\t\t\tthis.insertButtonView,\n\t\t\tthis.cancelButtonView\n\t\t];\n\n\t\tchildViews.forEach( v => {\n\t\t\t// Register the view as focusable.\n\t\t\tthis._focusables.add( v );\n\n\t\t\t// Register the view in the focus tracker.\n\t\t\tthis.focusTracker.add( v.element );\n\t\t} );\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element );\n\n\t\tconst stopPropagation = data => data.stopPropagation();\n\n\t\t// Since the form is in the dropdown panel which is a child of the toolbar, the toolbar's\n\t\t// keystroke handler would take over the key management in the URL input. We need to prevent\n\t\t// this ASAP. Otherwise, the basic caret movement using the arrow keys will be impossible.\n\t\tthis.keystrokes.set( 'arrowright', stopPropagation );\n\t\tthis.keystrokes.set( 'arrowleft', stopPropagation );\n\t\tthis.keystrokes.set( 'arrowup', stopPropagation );\n\t\tthis.keystrokes.set( 'arrowdown', stopPropagation );\n\n\t\t// Intercept the \"selectstart\" event, which is blocked by default because of the default behavior\n\t\t// of the DropdownView#panelView.\n\t\t// TODO: blocking \"selectstart\" in the #panelView should be configurable per–drop–down instance.\n\t\tthis.listenTo( childViews[ 0 ].element, 'selectstart', ( evt, domEvt ) => {\n\t\t\tdomEvt.stopPropagation();\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * Returns a view of the integration.\n\t *\n\t * @param {String} name The name of the integration.\n\t * @returns {module:ui/view~View}\n\t */\n\tgetIntegration( name ) {\n\t\treturn this._integrations.find( integration => integration.name === name );\n\t}\n\n\t/**\n\t * Creates the dropdown view.\n\t *\n\t * @param {module:utils/locale~Locale} locale The localization services instance.\n\t *\n\t * @private\n\t * @returns {module:ui/dropdown/dropdownview~DropdownView}\n\t */\n\t_createDropdownView( locale ) {\n\t\tconst t = locale.t;\n\t\tconst dropdownView = createDropdown( locale, SplitButtonView );\n\t\tconst splitButtonView = dropdownView.buttonView;\n\t\tconst panelView = dropdownView.panelView;\n\n\t\tsplitButtonView.set( {\n\t\t\tlabel: t( 'Insert image' ),\n\t\t\ticon: icons.image,\n\t\t\ttooltip: true\n\t\t} );\n\n\t\tpanelView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-image-insert__panel'\n\t\t\t}\n\t\t} );\n\n\t\treturn dropdownView;\n\t}\n\n\t/**\n\t * Creates the following form controls:\n\t *\n\t * * {@link #insertButtonView},\n\t * * {@link #cancelButtonView}.\n\t *\n\t * @param {module:utils/locale~Locale} locale The localization services instance.\n\t *\n\t * @private\n\t * @returns {Object.}\n\t */\n\t_createActionButtons( locale ) {\n\t\tconst t = locale.t;\n\t\tconst insertButtonView = new ButtonView( locale );\n\t\tconst cancelButtonView = new ButtonView( locale );\n\n\t\tinsertButtonView.set( {\n\t\t\tlabel: t( 'Insert' ),\n\t\t\ticon: icons.check,\n\t\t\tclass: 'ck-button-save',\n\t\t\ttype: 'submit',\n\t\t\twithText: true,\n\t\t\tisEnabled: this.imageURLInputValue\n\t\t} );\n\n\t\tcancelButtonView.set( {\n\t\t\tlabel: t( 'Cancel' ),\n\t\t\ticon: icons.cancel,\n\t\t\tclass: 'ck-button-cancel',\n\t\t\twithText: true\n\t\t} );\n\n\t\tinsertButtonView.bind( 'isEnabled' ).to( this, 'imageURLInputValue', value => !!value );\n\t\tinsertButtonView.delegate( 'execute' ).to( this, 'submit' );\n\t\tcancelButtonView.delegate( 'execute' ).to( this, 'cancel' );\n\n\t\treturn { insertButtonView, cancelButtonView };\n\t}\n\n\t/**\n\t * Focuses the first {@link #_focusables focusable} in the form.\n\t */\n\tfocus() {\n\t\tthis._focusCycler.focusFirst();\n\t}\n}\n\n/**\n * Fired when the form view is submitted (when one of the children triggered the submit event),\n * e.g. by a click on {@link #insertButtonView}.\n *\n * @event submit\n */\n\n/**\n * Fired when the form view is canceled, e.g. by a click on {@link #cancelButtonView}.\n *\n * @event cancel\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/imageinsert/utils\n */\n\nimport { LabeledFieldView, createLabeledInputText } from 'ckeditor5/src/ui';\n\n/**\n * Creates integrations object that will be passed to the\n * {@link module:image/imageinsert/ui/imageinsertpanelview~ImageInsertPanelView}.\n *\n * @param {module:core/editor/editor~Editor} editor Editor instance.\n *\n * @returns {Object.} Integrations object.\n */\nexport function prepareIntegrations( editor ) {\n\tconst panelItems = editor.config.get( 'image.insert.integrations' );\n\tconst imageInsertUIPlugin = editor.plugins.get( 'ImageInsertUI' );\n\n\tconst PREDEFINED_INTEGRATIONS = {\n\t\t'insertImageViaUrl': createLabeledInputView( editor.locale )\n\t};\n\n\tif ( !panelItems ) {\n\t\treturn PREDEFINED_INTEGRATIONS;\n\t}\n\n\t// Prepares ckfinder component for the `openCKFinder` integration token.\n\tif ( panelItems.find( item => item === 'openCKFinder' ) && editor.ui.componentFactory.has( 'ckfinder' ) ) {\n\t\tconst ckFinderButton = editor.ui.componentFactory.create( 'ckfinder' );\n\t\tckFinderButton.set( {\n\t\t\twithText: true,\n\t\t\tclass: 'ck-image-insert__ck-finder-button'\n\t\t} );\n\n\t\t// We want to close the dropdown panel view when user clicks the ckFinderButton.\n\t\tckFinderButton.delegate( 'execute' ).to( imageInsertUIPlugin, 'cancel' );\n\n\t\tPREDEFINED_INTEGRATIONS.openCKFinder = ckFinderButton;\n\t}\n\n\t// Creates integrations object of valid views to pass it to the ImageInsertPanelView.\n\treturn panelItems.reduce( ( object, key ) => {\n\t\tif ( PREDEFINED_INTEGRATIONS[ key ] ) {\n\t\t\tobject[ key ] = PREDEFINED_INTEGRATIONS[ key ];\n\t\t} else if ( editor.ui.componentFactory.has( key ) ) {\n\t\t\tobject[ key ] = editor.ui.componentFactory.create( key );\n\t\t}\n\n\t\treturn object;\n\t}, {} );\n}\n\n/**\n * Creates labeled field view.\n *\n * @param {module:utils/locale~Locale} locale The localization services instance.\n *\n * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView}\n */\nexport function createLabeledInputView( locale ) {\n\tconst t = locale.t;\n\tconst labeledInputView = new LabeledFieldView( locale, createLabeledInputText );\n\n\tlabeledInputView.set( {\n\t\tlabel: t( 'Insert image via URL' )\n\t} );\n\tlabeledInputView.fieldView.placeholder = 'https://example.com/image.png';\n\n\treturn labeledInputView;\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/imageinsert/imageinsertui\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport ImageInsertPanelView from './ui/imageinsertpanelview';\nimport { prepareIntegrations } from './utils';\n\nimport { isImage } from '../image/utils';\n\n/**\n * The image insert dropdown plugin.\n *\n * For a detailed overview, check the {@glink features/image-upload/image-upload Image upload feature}\n * and {@glink features/image#inserting-images-via-source-url Insert images via source URL} documentation.\n *\n * Adds the `'insertImage'` dropdown to the {@link module:ui/componentfactory~ComponentFactory UI component factory}\n * and also the `imageInsert` dropdown as an alias for backward compatibility.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageInsertUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageInsertUI';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst componentCreator = locale => {\n\t\t\treturn this._createDropdownView( locale );\n\t\t};\n\n\t\t// Register `insertImage` dropdown and add `imageInsert` dropdown as an alias for backward compatibility.\n\t\teditor.ui.componentFactory.add( 'insertImage', componentCreator );\n\t\teditor.ui.componentFactory.add( 'imageInsert', componentCreator );\n\t}\n\n\t/**\n\t * Creates the dropdown view.\n\t *\n\t * @param {module:utils/locale~Locale} locale The localization services instance.\n\t *\n\t * @private\n\t * @returns {module:ui/dropdown/dropdownview~DropdownView}\n\t */\n\t_createDropdownView( locale ) {\n\t\tconst editor = this.editor;\n\t\tconst imageInsertView = new ImageInsertPanelView( locale, prepareIntegrations( editor ) );\n\t\tconst command = editor.commands.get( 'uploadImage' );\n\n\t\tconst dropdownView = imageInsertView.dropdownView;\n\t\tconst splitButtonView = dropdownView.buttonView;\n\n\t\tsplitButtonView.actionView = editor.ui.componentFactory.create( 'uploadImage' );\n\t\t// After we replaced action button with `uploadImage` component,\n\t\t// we have lost a proper styling and some minor visual quirks have appeared.\n\t\t// Brining back original split button classes helps fix the button styling\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/7986.\n\t\tsplitButtonView.actionView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck ck-button ck-splitbutton__action'\n\t\t\t}\n\t\t} );\n\n\t\treturn this._setUpDropdown( dropdownView, imageInsertView, command );\n\t}\n\n\t/**\n\t * Sets up the dropdown view.\n\t *\n\t * @param {module:ui/dropdown/dropdownview~DropdownView} dropdownView A dropdownView.\n\t * @param {module:image/imageinsert/ui/imageinsertpanelview~ImageInsertPanelView} imageInsertView An imageInsertView.\n\t * @param {module:core/command~Command} command An insertImage command\n\t *\n\t * @private\n\t * @returns {module:ui/dropdown/dropdownview~DropdownView}\n\t */\n\t_setUpDropdown( dropdownView, imageInsertView, command ) {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\t\tconst insertButtonView = imageInsertView.insertButtonView;\n\t\tconst insertImageViaUrlForm = imageInsertView.getIntegration( 'insertImageViaUrl' );\n\t\tconst panelView = dropdownView.panelView;\n\n\t\tdropdownView.bind( 'isEnabled' ).to( command );\n\n\t\t// Defer the children injection to improve initial performance.\n\t\t// See https://github.com/ckeditor/ckeditor5/pull/8019#discussion_r484069652.\n\t\tdropdownView.buttonView.once( 'open', () => {\n\t\t\tpanelView.children.add( imageInsertView );\n\t\t} );\n\n\t\tdropdownView.on( 'change:isOpen', () => {\n\t\t\tconst selectedElement = editor.model.document.selection.getSelectedElement();\n\n\t\t\tif ( dropdownView.isOpen ) {\n\t\t\t\timageInsertView.focus();\n\n\t\t\t\tif ( isImage( selectedElement ) ) {\n\t\t\t\t\timageInsertView.imageURLInputValue = selectedElement.getAttribute( 'src' );\n\t\t\t\t\tinsertButtonView.label = t( 'Update' );\n\t\t\t\t\tinsertImageViaUrlForm.label = t( 'Update image URL' );\n\t\t\t\t} else {\n\t\t\t\t\timageInsertView.imageURLInputValue = '';\n\t\t\t\t\tinsertButtonView.label = t( 'Insert' );\n\t\t\t\t\tinsertImageViaUrlForm.label = t( 'Insert image via URL' );\n\t\t\t\t}\n\t\t\t}\n\t\t// Note: Use the low priority to make sure the following listener starts working after the\n\t\t// default action of the drop-down is executed (i.e. the panel showed up). Otherwise, the\n\t\t// invisible form/input cannot be focused/selected.\n\t\t}, { priority: 'low' } );\n\n\t\timageInsertView.delegate( 'submit', 'cancel' ).to( dropdownView );\n\t\tthis.delegate( 'cancel' ).to( dropdownView );\n\n\t\tdropdownView.on( 'submit', () => {\n\t\t\tclosePanel();\n\t\t\tonSubmit();\n\t\t} );\n\n\t\tdropdownView.on( 'cancel', () => {\n\t\t\tclosePanel();\n\t\t} );\n\n\t\tfunction onSubmit() {\n\t\t\tconst selectedElement = editor.model.document.selection.getSelectedElement();\n\n\t\t\tif ( isImage( selectedElement ) ) {\n\t\t\t\teditor.model.change( writer => {\n\t\t\t\t\twriter.setAttribute( 'src', imageInsertView.imageURLInputValue, selectedElement );\n\t\t\t\t\twriter.removeAttribute( 'srcset', selectedElement );\n\t\t\t\t\twriter.removeAttribute( 'sizes', selectedElement );\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\teditor.execute( 'insertImage', { source: imageInsertView.imageURLInputValue } );\n\t\t\t}\n\t\t}\n\n\t\tfunction closePanel() {\n\t\t\teditor.editing.view.focus();\n\t\t\tdropdownView.isOpen = false;\n\t\t}\n\n\t\treturn dropdownView;\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/imageinsert\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport ImageUpload from './imageupload';\nimport ImageInsertUI from './imageinsert/imageinsertui';\n\n/**\n * The image insert plugin.\n *\n * For a detailed overview, check the {@glink features/image-upload/image-upload Image upload feature}\n * and {@glink features/image#inserting-images-via-source-url Insert images via source URL} documentation.\n *\n * This plugin does not do anything directly, but it loads a set of specific plugins\n * to enable image uploading or inserting via implemented integrations:\n *\n * * {@link module:image/imageupload~ImageUpload}\n * * {@link module:image/imageinsert/imageinsertui~ImageInsertUI},\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageInsert extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageInsert';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ImageUpload, ImageInsertUI ];\n\t}\n}\n\n/**\n * The image insert configuration.\n *\n * @protected\n * @member {module:image/imageinsert~ImageInsertConfig} module:image/image~ImageConfig#insert\n */\n\n/**\n * The configuration of the image insert dropdown panel view. Used by the image insert 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\tinsert: {\n *\t\t\t\t\t\t... // settings for \"insertImage\" view goes here\n * \t\t\t\t\t}\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 * @protected\n * @interface module:image/imageinsert~ImageInsertConfig\n */\n\n/**\n * The image insert panel view configuration contains a list of {@link module:image/imageinsert~ImageInsert} integrations.\n *\n * The option accepts string tokens.\n * * for predefined integrations, we have two special strings: `insertImageViaUrl` and `openCKFinder`.\n * The former adds the **Insert image via URL** feature, while the latter adds the built-in **CKFinder** integration.\n * * for custom integrations, each string should be a name of the component registered in the\n * {@link module:ui/componentfactory~ComponentFactory component factory}.\n * If you have a plugin `PluginX` that registers `pluginXButton` component, then the integration token\n * in that case should be `pluginXButton`.\n *\n *\t\t// Add `insertImageViaUrl`, `openCKFinder` and custom `pluginXButton` integrations.\n *\t\tconst imageInsertConfig = {\n *\t\t\tinsert: {\n *\t\t\t\tintegrations: [\n *\t\t\t\t\t'insertImageViaUrl',\n *\t\t\t\t\t'openCKFinder',\n *\t\t\t\t\t'pluginXButton'\n *\t\t\t\t]\n *\t\t\t}\n *\t\t};\n *\n * @member {Array.} module:image/imageinsert~ImageInsertConfig#integrations\n * @default [ 'insertImageViaUrl' ]\n */\n","module.exports = \"\"","/**\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/image/imageloadobserver\n */\n\nimport { Observer } from 'ckeditor5/src/engine';\n\n/**\n * Observes all new images added to the {@link module:engine/view/document~Document},\n * fires {@link module:engine/view/document~Document#event:imageLoaded} and\n * {@link module:engine/view/document~Document#event:layoutChanged} event every time when the new image\n * has been loaded.\n *\n * **Note:** This event is not fired for images that has been added to the document and rendered as `complete` (already loaded).\n *\n * @extends module:engine/view/observer/observer~Observer\n */\nexport default class ImageLoadObserver extends Observer {\n\t/**\n\t * @inheritDoc\n\t */\n\tobserve( domRoot ) {\n\t\tthis.listenTo( domRoot, 'load', ( event, domEvent ) => {\n\t\t\tconst domElement = domEvent.target;\n\n\t\t\tif ( this.checkShouldIgnoreEventFromTarget( domElement ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( domElement.tagName == 'IMG' ) {\n\t\t\t\tthis._fireEvents( domEvent );\n\t\t\t}\n\t\t\t// Use capture phase for better performance (#4504).\n\t\t}, { useCapture: true } );\n\t}\n\n\t/**\n\t * Fires {@link module:engine/view/document~Document#event:layoutChanged} and\n\t * {@link module:engine/view/document~Document#event:imageLoaded}\n\t * if observer {@link #isEnabled is enabled}.\n\t *\n\t * @protected\n\t * @param {Event} domEvent The DOM event.\n\t */\n\t_fireEvents( domEvent ) {\n\t\tif ( this.isEnabled ) {\n\t\t\tthis.document.fire( 'layoutChanged' );\n\t\t\tthis.document.fire( 'imageLoaded', domEvent );\n\t\t}\n\t}\n}\n\n/**\n * Fired when an DOM element has been loaded in the DOM root.\n *\n * Introduced by {@link module:image/image/imageloadobserver~ImageLoadObserver}.\n *\n * @see module:image/image/imageloadobserver~ImageLoadObserver\n * @event module:engine/view/document~Document#event:imageLoaded\n * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.\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/image/converters\n */\n\nimport { first } from 'ckeditor5/src/utils';\nimport { getViewImgFromWidget } from './utils';\n\n/**\n * Returns a function that converts the image view representation:\n *\n *\t\t
\"...\"
\n *\n * to the model representation:\n *\n *\t\t\"...\"\n *\n * The entire content of the `
` element except the first `` is being converted as children\n * of the `` model element.\n *\n * @returns {Function}\n */\nexport function viewFigureToModel() {\n\treturn dispatcher => {\n\t\tdispatcher.on( 'element:figure', converter );\n\t};\n\n\tfunction converter( evt, data, conversionApi ) {\n\t\t// Do not convert if this is not an \"image figure\".\n\t\tif ( !conversionApi.consumable.test( data.viewItem, { name: true, classes: 'image' } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Find an image element inside the figure element.\n\t\tconst viewImage = getViewImgFromWidget( data.viewItem );\n\n\t\t// Do not convert if image element is absent, is missing src attribute or was already converted.\n\t\tif ( !viewImage || !viewImage.hasAttribute( 'src' ) || !conversionApi.consumable.test( viewImage, { name: true } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Convert view image to model image.\n\t\tconst conversionResult = conversionApi.convertItem( viewImage, data.modelCursor );\n\n\t\t// Get image element from conversion result.\n\t\tconst modelImage = first( conversionResult.modelRange.getItems() );\n\n\t\t// When image wasn't successfully converted then finish conversion.\n\t\tif ( !modelImage ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Convert rest of the figure element's children as an image children.\n\t\tconversionApi.convertChildren( data.viewItem, modelImage );\n\n\t\tconversionApi.updateConversionResult( modelImage, data );\n\t}\n}\n\n/**\n * Converter used to convert the `srcset` model image attribute to the `srcset`, `sizes` and `width` attributes in the view.\n *\n * @returns {Function}\n */\nexport function srcsetAttributeConverter() {\n\treturn dispatcher => {\n\t\tdispatcher.on( 'attribute:srcset:image', converter );\n\t};\n\n\tfunction converter( evt, data, conversionApi ) {\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst writer = conversionApi.writer;\n\t\tconst figure = conversionApi.mapper.toViewElement( data.item );\n\t\tconst img = getViewImgFromWidget( figure );\n\n\t\tif ( data.attributeNewValue === null ) {\n\t\t\tconst srcset = data.attributeOldValue;\n\n\t\t\tif ( srcset.data ) {\n\t\t\t\twriter.removeAttribute( 'srcset', img );\n\t\t\t\twriter.removeAttribute( 'sizes', img );\n\n\t\t\t\tif ( srcset.width ) {\n\t\t\t\t\twriter.removeAttribute( 'width', img );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst srcset = data.attributeNewValue;\n\n\t\t\tif ( srcset.data ) {\n\t\t\t\twriter.setAttribute( 'srcset', srcset.data, img );\n\t\t\t\t// Always outputting `100vw`. See https://github.com/ckeditor/ckeditor5-image/issues/2.\n\t\t\t\twriter.setAttribute( 'sizes', '100vw', img );\n\n\t\t\t\tif ( srcset.width ) {\n\t\t\t\t\twriter.setAttribute( 'width', srcset.width, img );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport function modelToViewAttributeConverter( attributeKey ) {\n\treturn dispatcher => {\n\t\tdispatcher.on( `attribute:${ attributeKey }:image`, converter );\n\t};\n\n\tfunction converter( evt, data, conversionApi ) {\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst figure = conversionApi.mapper.toViewElement( data.item );\n\t\tconst img = getViewImgFromWidget( figure );\n\n\t\tviewWriter.setAttribute( data.attributeKey, data.attributeNewValue || '', img );\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\nimport { Command } from 'ckeditor5/src/core';\nimport { toArray } from 'ckeditor5/src/utils';\n\nimport { insertImage, isImageAllowed } from './utils';\n\n/**\n * @module image/image/insertimagecommand\n */\n\n/**\n * Insert image command.\n *\n * The command is registered by the {@link module:image/image/imageediting~ImageEditing} plugin as `insertImage`\n * and it is also available via aliased `imageInsert` name.\n *\n * In order to insert an image at the current selection position\n * (according to the {@link module:widget/utils~findOptimalInsertionPosition} algorithm),\n * execute the command and specify the image source:\n *\n *\t\teditor.execute( 'insertImage', { source: 'http://url.to.the/image' } );\n *\n * It is also possible to insert multiple images at once:\n *\n *\t\teditor.execute( 'insertImage', {\n *\t\t\tsource: [\n *\t\t\t\t'path/to/image.jpg',\n *\t\t\t\t'path/to/other-image.jpg'\n *\t\t\t]\n *\t\t} );\n *\n * @extends module:core/command~Command\n */\nexport default class InsertImageCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = isImageAllowed( this.editor.model );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options Options for the executed command.\n\t * @param {String|Array.} options.source The image source or an array of image sources to insert.\n\t */\n\texecute( options ) {\n\t\tconst model = this.editor.model;\n\n\t\tfor ( const src of toArray( options.source ) ) {\n\t\t\tinsertImage( model, { src } );\n\t\t}\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/image/imageediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport ImageLoadObserver from './imageloadobserver';\n\nimport {\n\tviewFigureToModel,\n\tmodelToViewAttributeConverter,\n\tsrcsetAttributeConverter\n} from './converters';\n\nimport { toImageWidget } from './utils';\n\nimport InsertImageCommand from './insertimagecommand';\n\n/**\n * The image engine plugin.\n *\n * It registers:\n *\n * * `` as a block element in the document schema, and allows `alt`, `src` and `srcset` attributes.\n * * converters for editing and data pipelines.\n * * `'insertImage'` command.\n * * `'imageInsert'` command as an alias for `insertImage` command.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\t\tconst t = editor.t;\n\t\tconst conversion = editor.conversion;\n\n\t\t// See https://github.com/ckeditor/ckeditor5-image/issues/142.\n\t\teditor.editing.view.addObserver( ImageLoadObserver );\n\n\t\t// Configure schema.\n\t\tschema.register( 'image', {\n\t\t\tisObject: true,\n\t\t\tisBlock: true,\n\t\t\tallowWhere: '$block',\n\t\t\tallowAttributes: [ 'alt', 'src', 'srcset' ]\n\t\t} );\n\n\t\tconversion.for( 'dataDowncast' ).elementToElement( {\n\t\t\tmodel: 'image',\n\t\t\tview: ( modelElement, { writer } ) => createImageViewElement( writer )\n\t\t} );\n\n\t\tconversion.for( 'editingDowncast' ).elementToElement( {\n\t\t\tmodel: 'image',\n\t\t\tview: ( modelElement, { writer } ) => toImageWidget( createImageViewElement( writer ), writer, t( 'image widget' ) )\n\t\t} );\n\n\t\tconversion.for( 'downcast' )\n\t\t\t.add( modelToViewAttributeConverter( 'src' ) )\n\t\t\t.add( modelToViewAttributeConverter( 'alt' ) )\n\t\t\t.add( srcsetAttributeConverter() );\n\n\t\tconversion.for( 'upcast' )\n\t\t\t.elementToElement( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'img',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tsrc: true\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tmodel: ( viewImage, { writer } ) => writer.createElement( 'image', { src: viewImage.getAttribute( 'src' ) } )\n\t\t\t} )\n\t\t\t.attributeToAttribute( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'img',\n\t\t\t\t\tkey: 'alt'\n\t\t\t\t},\n\t\t\t\tmodel: 'alt'\n\t\t\t} )\n\t\t\t.attributeToAttribute( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'img',\n\t\t\t\t\tkey: 'srcset'\n\t\t\t\t},\n\t\t\t\tmodel: {\n\t\t\t\t\tkey: 'srcset',\n\t\t\t\t\tvalue: viewImage => {\n\t\t\t\t\t\tconst value = {\n\t\t\t\t\t\t\tdata: viewImage.getAttribute( 'srcset' )\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif ( viewImage.hasAttribute( 'width' ) ) {\n\t\t\t\t\t\t\tvalue.width = viewImage.getAttribute( 'width' );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.add( viewFigureToModel() );\n\n\t\tconst insertImageCommand = new InsertImageCommand( editor );\n\n\t\t// Register `insertImage` command and add `imageInsert` command as an alias for backward compatibility.\n\t\teditor.commands.add( 'insertImage', insertImageCommand );\n\t\teditor.commands.add( 'imageInsert', insertImageCommand );\n\t}\n}\n\n// Creates a view element representing the image.\n//\n//\t\t
\n//\n// Note that `alt` and `src` attributes are converted separately, so they are not included.\n//\n// @private\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @returns {module:engine/view/containerelement~ContainerElement}\nexport function createImageViewElement( writer ) {\n\tconst emptyElement = writer.createEmptyElement( 'img' );\n\tconst figure = writer.createContainerElement( 'figure', { class: 'image' } );\n\n\twriter.insert( writer.createPositionAt( figure, 0 ), emptyElement );\n\n\treturn figure;\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/imagetextalternative/imagetextalternativecommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { isImage } from '../image/utils';\n\n/**\n * The image text alternative command. It is used to change the `alt` attribute of `` elements.\n *\n * @extends module:core/command~Command\n */\nexport default class ImageTextAlternativeCommand extends Command {\n\t/**\n\t * The command value: `false` if there is no `alt` attribute, otherwise the value of the `alt` attribute.\n\t *\n\t * @readonly\n\t * @observable\n\t * @member {String|Boolean} #value\n\t */\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst element = this.editor.model.document.selection.getSelectedElement();\n\n\t\tthis.isEnabled = isImage( element );\n\n\t\tif ( isImage( element ) && element.hasAttribute( 'alt' ) ) {\n\t\t\tthis.value = element.getAttribute( 'alt' );\n\t\t} else {\n\t\t\tthis.value = false;\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options\n\t * @param {String} options.newValue The new value of the `alt` attribute to set.\n\t */\n\texecute( options ) {\n\t\tconst model = this.editor.model;\n\t\tconst imageElement = model.document.selection.getSelectedElement();\n\n\t\tmodel.change( writer => {\n\t\t\twriter.setAttribute( 'alt', options.newValue, imageElement );\n\t\t} );\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/imagetextalternative/imagetextalternativeediting\n */\n\nimport ImageTextAlternativeCommand from './imagetextalternativecommand';\nimport { Plugin } from 'ckeditor5/src/core';\n\n/**\n * The image text alternative editing plugin.\n *\n * Registers the `'imageTextAlternative'` command.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageTextAlternativeEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageTextAlternativeEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tthis.editor.commands.add( 'imageTextAlternative', new ImageTextAlternativeCommand( this.editor ) );\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/imagetextalternative/ui/textalternativeformview\n */\n\nimport {\n\tButtonView,\n\tFocusCycler,\n\tLabeledFieldView,\n\tView,\n\tViewCollection,\n\tcreateLabeledInputText,\n\tinjectCssTransitionDisabler,\n\tsubmitHandler\n} from 'ckeditor5/src/ui';\nimport { FocusTracker, KeystrokeHandler } from 'ckeditor5/src/utils';\nimport { icons } from 'ckeditor5/src/core';\n\nimport '../../../theme/textalternativeform.css';\n\n// See: #8833.\n// eslint-disable-next-line ckeditor5-rules/ckeditor-imports\nimport '@ckeditor/ckeditor5-ui/theme/components/responsive-form/responsiveform.css';\n\n/**\n * The TextAlternativeFormView class.\n *\n * @extends module:ui/view~View\n */\nexport default class TextAlternativeFormView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tconst t = this.locale.t;\n\n\t\t/**\n\t\t * Tracks information about the DOM focus in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker}\n\t\t */\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\t/**\n\t\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\t/**\n\t\t * An input with a label.\n\t\t *\n\t\t * @member {module:ui/labeledfield/labeledfieldview~LabeledFieldView} #labeledInput\n\t\t */\n\t\tthis.labeledInput = this._createLabeledInputView();\n\n\t\t/**\n\t\t * A button used to submit the form.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView} #saveButtonView\n\t\t */\n\t\tthis.saveButtonView = this._createButton( t( 'Save' ), icons.check, 'ck-button-save' );\n\t\tthis.saveButtonView.type = 'submit';\n\n\t\t/**\n\t\t * A button used to cancel the form.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView} #cancelButtonView\n\t\t */\n\t\tthis.cancelButtonView = this._createButton( t( 'Cancel' ), icons.cancel, 'ck-button-cancel', 'cancel' );\n\n\t\t/**\n\t\t * A collection of views which can be focused in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis._focusables = new ViewCollection();\n\n\t\t/**\n\t\t * Helps cycling over {@link #_focusables} in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/focuscycler~FocusCycler}\n\t\t */\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate form fields backwards using the Shift + Tab keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate form fields forwards using the Tab key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'form',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-text-alternative-form',\n\t\t\t\t\t'ck-responsive-form'\n\t\t\t\t],\n\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-image/issues/40\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\tthis.labeledInput,\n\t\t\t\tthis.saveButtonView,\n\t\t\t\tthis.cancelButtonView\n\t\t\t]\n\t\t} );\n\n\t\tinjectCssTransitionDisabler( this );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tthis.keystrokes.listenTo( this.element );\n\n\t\tsubmitHandler( { view: this } );\n\n\t\t[ this.labeledInput, this.saveButtonView, this.cancelButtonView ]\n\t\t\t.forEach( v => {\n\t\t\t\t// Register the view as focusable.\n\t\t\t\tthis._focusables.add( v );\n\n\t\t\t\t// Register the view in the focus tracker.\n\t\t\t\tthis.focusTracker.add( v.element );\n\t\t\t} );\n\t}\n\n\t/**\n\t * Creates the button view.\n\t *\n\t * @private\n\t * @param {String} label The button label\n\t * @param {String} icon The button's icon.\n\t * @param {String} className The additional button CSS class name.\n\t * @param {String} [eventName] The event name that the ButtonView#execute event will be delegated to.\n\t * @returns {module:ui/button/buttonview~ButtonView} The button view instance.\n\t */\n\t_createButton( label, icon, className, eventName ) {\n\t\tconst button = new ButtonView( this.locale );\n\n\t\tbutton.set( {\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\ttooltip: true\n\t\t} );\n\n\t\tbutton.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: className\n\t\t\t}\n\t\t} );\n\n\t\tif ( eventName ) {\n\t\t\tbutton.delegate( 'execute' ).to( this, eventName );\n\t\t}\n\n\t\treturn button;\n\t}\n\n\t/**\n\t * Creates an input with a label.\n\t *\n\t * @private\n\t * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView} Labeled field view instance.\n\t */\n\t_createLabeledInputView() {\n\t\tconst t = this.locale.t;\n\t\tconst labeledInput = new LabeledFieldView( this.locale, createLabeledInputText );\n\n\t\tlabeledInput.label = t( 'Text alternative' );\n\n\t\treturn labeledInput;\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/image/ui/utils\n */\n\nimport { BalloonPanelView } from 'ckeditor5/src/ui';\nimport { getSelectedImageWidget } from '../utils';\n\n/**\n * A helper utility that positions the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} instance\n * with respect to the image in the editor content, if one is selected.\n *\n * @param {module:core/editor/editor~Editor} editor The editor instance.\n */\nexport function repositionContextualBalloon( editor ) {\n\tconst balloon = editor.plugins.get( 'ContextualBalloon' );\n\n\tif ( getSelectedImageWidget( editor.editing.view.document.selection ) ) {\n\t\tconst position = getBalloonPositionData( editor );\n\n\t\tballoon.updatePosition( position );\n\t}\n}\n\n/**\n * Returns the positioning options that control the geometry of the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} with respect\n * to the selected element in the editor content.\n *\n * @param {module:core/editor/editor~Editor} editor The editor instance.\n * @returns {module:utils/dom/position~Options}\n */\nexport function getBalloonPositionData( editor ) {\n\tconst editingView = editor.editing.view;\n\tconst defaultPositions = BalloonPanelView.defaultPositions;\n\n\treturn {\n\t\ttarget: editingView.domConverter.viewToDom( editingView.document.selection.getSelectedElement() ),\n\t\tpositions: [\n\t\t\tdefaultPositions.northArrowSouth,\n\t\t\tdefaultPositions.northArrowSouthWest,\n\t\t\tdefaultPositions.northArrowSouthEast,\n\t\t\tdefaultPositions.southArrowNorth,\n\t\t\tdefaultPositions.southArrowNorthWest,\n\t\t\tdefaultPositions.southArrowNorthEast\n\t\t]\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/imagetextalternative/imagetextalternativeui\n */\n\nimport { Plugin, icons } from 'ckeditor5/src/core';\nimport { ButtonView, ContextualBalloon, clickOutsideHandler } from 'ckeditor5/src/ui';\n\nimport TextAlternativeFormView from './ui/textalternativeformview';\nimport { repositionContextualBalloon, getBalloonPositionData } from '../image/ui/utils';\nimport { getSelectedImageWidget } from '../image/utils';\n\n/**\n * The image text alternative UI plugin.\n *\n * The plugin uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageTextAlternativeUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ContextualBalloon ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageTextAlternativeUI';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tthis._createButton();\n\t\tthis._createForm();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\n\t\t// Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).\n\t\tthis._form.destroy();\n\t}\n\n\t/**\n\t * Creates a button showing the balloon panel for changing the image text alternative and\n\t * registers it in the editor {@link module:ui/componentfactory~ComponentFactory ComponentFactory}.\n\t *\n\t * @private\n\t */\n\t_createButton() {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\n\t\teditor.ui.componentFactory.add( 'imageTextAlternative', locale => {\n\t\t\tconst command = editor.commands.get( 'imageTextAlternative' );\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: t( 'Change image text alternative' ),\n\t\t\t\ticon: icons.lowVision,\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\tview.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\n\t\t\tthis.listenTo( view, 'execute', () => {\n\t\t\t\tthis._showForm();\n\t\t\t} );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n\n\t/**\n\t * Creates the {@link module:image/imagetextalternative/ui/textalternativeformview~TextAlternativeFormView}\n\t * form.\n\t *\n\t * @private\n\t */\n\t_createForm() {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\t/**\n\t\t * The contextual balloon plugin instance.\n\t\t *\n\t\t * @private\n\t\t * @member {module:ui/panel/balloon/contextualballoon~ContextualBalloon}\n\t\t */\n\t\tthis._balloon = this.editor.plugins.get( 'ContextualBalloon' );\n\n\t\t/**\n\t\t * A form containing a textarea and buttons, used to change the `alt` text value.\n\t\t *\n\t\t * @member {module:image/imagetextalternative/ui/textalternativeformview~TextAlternativeFormView}\n\t\t */\n\t\tthis._form = new TextAlternativeFormView( editor.locale );\n\n\t\t// Render the form so its #element is available for clickOutsideHandler.\n\t\tthis._form.render();\n\n\t\tthis.listenTo( this._form, 'submit', () => {\n\t\t\teditor.execute( 'imageTextAlternative', {\n\t\t\t\tnewValue: this._form.labeledInput.fieldView.element.value\n\t\t\t} );\n\n\t\t\tthis._hideForm( true );\n\t\t} );\n\n\t\tthis.listenTo( this._form, 'cancel', () => {\n\t\t\tthis._hideForm( true );\n\t\t} );\n\n\t\t// Close the form on Esc key press.\n\t\tthis._form.keystrokes.set( 'Esc', ( data, cancel ) => {\n\t\t\tthis._hideForm( true );\n\t\t\tcancel();\n\t\t} );\n\n\t\t// Reposition the balloon or hide the form if an image widget is no longer selected.\n\t\tthis.listenTo( editor.ui, 'update', () => {\n\t\t\tif ( !getSelectedImageWidget( viewDocument.selection ) ) {\n\t\t\t\tthis._hideForm( true );\n\t\t\t} else if ( this._isVisible ) {\n\t\t\t\trepositionContextualBalloon( editor );\n\t\t\t}\n\t\t} );\n\n\t\t// Close on click outside of balloon panel element.\n\t\tclickOutsideHandler( {\n\t\t\temitter: this._form,\n\t\t\tactivator: () => this._isVisible,\n\t\t\tcontextElements: [ this._balloon.view.element ],\n\t\t\tcallback: () => this._hideForm()\n\t\t} );\n\t}\n\n\t/**\n\t * Shows the {@link #_form} in the {@link #_balloon}.\n\t *\n\t * @private\n\t */\n\t_showForm() {\n\t\tif ( this._isVisible ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst editor = this.editor;\n\t\tconst command = editor.commands.get( 'imageTextAlternative' );\n\t\tconst labeledInput = this._form.labeledInput;\n\n\t\tthis._form.disableCssTransitions();\n\n\t\tif ( !this._isInBalloon ) {\n\t\t\tthis._balloon.add( {\n\t\t\t\tview: this._form,\n\t\t\t\tposition: getBalloonPositionData( editor )\n\t\t\t} );\n\t\t}\n\n\t\t// Make sure that each time the panel shows up, the field remains in sync with the value of\n\t\t// the command. If the user typed in the input, then canceled the balloon (`labeledInput#value`\n\t\t// stays unaltered) and re-opened it without changing the value of the command, they would see the\n\t\t// old value instead of the actual value of the command.\n\t\t// https://github.com/ckeditor/ckeditor5-image/issues/114\n\t\tlabeledInput.fieldView.value = labeledInput.fieldView.element.value = command.value || '';\n\n\t\tthis._form.labeledInput.fieldView.select();\n\n\t\tthis._form.enableCssTransitions();\n\t}\n\n\t/**\n\t * Removes the {@link #_form} from the {@link #_balloon}.\n\t *\n\t * @param {Boolean} [focusEditable=false] Controls whether the editing view is focused afterwards.\n\t * @private\n\t */\n\t_hideForm( focusEditable ) {\n\t\tif ( !this._isInBalloon ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Blur the input element before removing it from DOM to prevent issues in some browsers.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/1501.\n\t\tif ( this._form.focusTracker.isFocused ) {\n\t\t\tthis._form.saveButtonView.focus();\n\t\t}\n\n\t\tthis._balloon.remove( this._form );\n\n\t\tif ( focusEditable ) {\n\t\t\tthis.editor.editing.view.focus();\n\t\t}\n\t}\n\n\t/**\n\t * Returns `true` when the {@link #_form} is the visible view in the {@link #_balloon}.\n\t *\n\t * @private\n\t * @type {Boolean}\n\t */\n\tget _isVisible() {\n\t\treturn this._balloon.visibleView === this._form;\n\t}\n\n\t/**\n\t * Returns `true` when the {@link #_form} is in the {@link #_balloon}.\n\t *\n\t * @private\n\t * @type {Boolean}\n\t */\n\tget _isInBalloon() {\n\t\treturn this._balloon.hasView( this._form );\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/imagetextalternative\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport ImageTextAlternativeEditing from './imagetextalternative/imagetextalternativeediting';\nimport ImageTextAlternativeUI from './imagetextalternative/imagetextalternativeui';\n\n/**\n * The image text alternative plugin.\n *\n * For a detailed overview, check the {@glink features/image#image-styles image styles} documentation.\n *\n * This is a \"glue\" plugin which loads the\n * {@link module:image/imagetextalternative/imagetextalternativeediting~ImageTextAlternativeEditing}\n * and {@link module:image/imagetextalternative/imagetextalternativeui~ImageTextAlternativeUI} plugins.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageTextAlternative extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ImageTextAlternativeEditing, ImageTextAlternativeUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageTextAlternative';\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/image\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { Widget } from 'ckeditor5/src/widget';\n\nimport ImageEditing from './image/imageediting';\nimport ImageTextAlternative from './imagetextalternative';\nimport { isImageWidget } from './image/utils';\n\nimport '../theme/image.css';\n\n/**\n * The image plugin.\n *\n * For a detailed overview, check the {@glink features/image image feature} documentation.\n *\n * This is a \"glue\" plugin which loads the following plugins:\n *\n * * {@link module:image/image/imageediting~ImageEditing},\n * * {@link module:image/imagetextalternative~ImageTextAlternative}.\n *\n * Usually, it is used in conjuction with other plugins from this package. See the {@glink api/image package page}\n * for more information.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Image extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ImageEditing, Widget, ImageTextAlternative ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Image';\n\t}\n\n\t/**\n\t * Checks if a given view element is an image widget.\n\t *\n\t * @param {module:engine/view/element~Element} viewElement\n\t * @returns {Boolean}\n\t */\n\tisImageWidget( viewElement ) {\n\t\treturn isImageWidget( viewElement );\n\t}\n}\n\n/**\n * The configuration of the image features. Used by the image features in the `@ckeditor/ckeditor5-image` package.\n *\n * Read more in {@link module:image/image~ImageConfig}.\n *\n * @member {module:image/image~ImageConfig} module:core/editor/editorconfig~EditorConfig#image\n */\n\n/**\n * The configuration of the image features. Used by the image features in the `@ckeditor/ckeditor5-image` package.\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n * \t\t\t\timage: ... // Image feature options.\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 ImageConfig\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/image/utils\n */\n\nimport { findOptimalInsertionPosition, checkSelectionOnObject, isWidget, toWidget } from 'ckeditor5/src/widget';\n\n/**\n * Converts a given {@link module:engine/view/element~Element} to an image widget:\n * * Adds a {@link module:engine/view/element~Element#_setCustomProperty custom property} allowing to recognize the image widget element.\n * * Calls the {@link module:widget/utils~toWidget} function with the proper element's label creator.\n *\n * @param {module:engine/view/element~Element} viewElement\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer An instance of the view writer.\n * @param {String} label The element's label. It will be concatenated with the image `alt` attribute if one is present.\n * @returns {module:engine/view/element~Element}\n */\nexport function toImageWidget( viewElement, writer, label ) {\n\twriter.setCustomProperty( 'image', true, viewElement );\n\n\treturn toWidget( viewElement, writer, { label: labelCreator } );\n\n\tfunction labelCreator() {\n\t\tconst imgElement = getViewImgFromWidget( viewElement );\n\t\tconst altText = imgElement.getAttribute( 'alt' );\n\n\t\treturn altText ? `${ altText } ${ label }` : label;\n\t}\n}\n\n/**\n * Checks if a given view element is an image widget.\n *\n * @param {module:engine/view/element~Element} viewElement\n * @returns {Boolean}\n */\nexport function isImageWidget( viewElement ) {\n\treturn !!viewElement.getCustomProperty( 'image' ) && isWidget( viewElement );\n}\n\n/**\n * Returns an image widget editing view element if one is selected.\n *\n * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} selection\n * @returns {module:engine/view/element~Element|null}\n */\nexport function getSelectedImageWidget( selection ) {\n\tconst viewElement = selection.getSelectedElement();\n\n\tif ( viewElement && isImageWidget( viewElement ) ) {\n\t\treturn viewElement;\n\t}\n\n\treturn null;\n}\n\n/**\n * Checks if the provided model element is an `image`.\n *\n * @param {module:engine/model/element~Element} modelElement\n * @returns {Boolean}\n */\nexport function isImage( modelElement ) {\n\treturn !!modelElement && modelElement.is( 'element', 'image' );\n}\n\n/**\n * Handles inserting single file. This method unifies image insertion using {@link module:widget/utils~findOptimalInsertionPosition} method.\n *\n *\t\tinsertImage( model, { src: 'path/to/image.jpg' } );\n *\n * @param {module:engine/model/model~Model} model\n * @param {Object} [attributes={}] Attributes of inserted image\n * @param {module:engine/model/position~Position} [insertPosition] Position to insert the image. If not specified,\n * the {@link module:widget/utils~findOptimalInsertionPosition} logic will be applied.\n */\nexport function insertImage( model, attributes = {}, insertPosition = null ) {\n\tmodel.change( writer => {\n\t\tconst imageElement = writer.createElement( 'image', attributes );\n\n\t\tconst insertAtSelection = insertPosition || findOptimalInsertionPosition( model.document.selection, model );\n\n\t\tmodel.insertContent( imageElement, insertAtSelection );\n\n\t\t// Inserting an image might've failed due to schema regulations.\n\t\tif ( imageElement.parent ) {\n\t\t\twriter.setSelection( imageElement, 'on' );\n\t\t}\n\t} );\n}\n\n/**\n * Checks if image can be inserted at current model selection.\n *\n * @param {module:engine/model/model~Model} model\n * @returns {Boolean}\n */\nexport function isImageAllowed( model ) {\n\tconst schema = model.schema;\n\tconst selection = model.document.selection;\n\n\treturn isImageAllowedInParent( selection, schema, model ) &&\n\t\t!checkSelectionOnObject( selection, schema ) &&\n\t\tisInOtherImage( selection );\n}\n\n/**\n * Get view `` element from the view widget (`
`).\n *\n * Assuming that image is always a first child of a widget (ie. `figureView.getChild( 0 )`) is unsafe as other features might\n * inject their own elements to the widget.\n *\n * The `` can be wrapped to other elements, e.g. ``. Nested check required.\n *\n * @param {module:engine/view/element~Element} figureView\n * @returns {module:engine/view/element~Element}\n */\nexport function getViewImgFromWidget( figureView ) {\n\tconst figureChildren = [];\n\n\tfor ( const figureChild of figureView.getChildren() ) {\n\t\tfigureChildren.push( figureChild );\n\n\t\tif ( figureChild.is( 'element' ) ) {\n\t\t\tfigureChildren.push( ...figureChild.getChildren() );\n\t\t}\n\t}\n\n\treturn figureChildren.find( viewChild => viewChild.is( 'element', 'img' ) );\n}\n\n// Checks if image is allowed by schema in optimal insertion parent.\n//\n// @returns {Boolean}\nfunction isImageAllowedInParent( selection, schema, model ) {\n\tconst parent = getInsertImageParent( selection, model );\n\n\treturn schema.checkChild( parent, 'image' );\n}\n\n// Checks if selection is placed in other image (ie. in caption).\nfunction isInOtherImage( selection ) {\n\treturn [ ...selection.focus.getAncestors() ].every( ancestor => !ancestor.is( 'element', 'image' ) );\n}\n\n// Returns a node that will be used to insert image with `model.insertContent` to check if image can be placed there.\nfunction getInsertImageParent( selection, model ) {\n\tconst insertAt = findOptimalInsertionPosition( selection, model );\n\n\tconst parent = insertAt.parent;\n\n\tif ( parent.isEmpty && !parent.is( 'element', '$root' ) ) {\n\t\treturn parent.parent;\n\t}\n\n\treturn parent;\n}\n"],"sourceRoot":""}