{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imageupload/utils.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imageupload/uploadimagecommand.js"],"names":["createImageTypeRegExp","types","regExpSafeNames","map","type","replace","RegExp","concat","join","fetchLocalImage","image","Promise","resolve","reject","imageSrc","getAttribute","fetch","then","resource","blob","mimeType","getImageMimeType","ext","filename","file","File","catch","err","name","convertLocalImageOnCanvas","isLocalImage","imageUtils","node","isInlineImageView","match","src","toLowerCase","getBlobFromCanvas","global","document","createElement","addEventListener","canvas","width","height","ctx","getContext","drawImage","toBlob","UploadImageCommand","editor","this","plugins","get","selectedElement","model","selection","getSelectedElement","isEnabled","isImageAllowed","isImage","options","_this","files","toArray","selectionAttributes","Object","fromEntries","getAttributes","forEach","index","position","createPositionAfter","_uploadImage","attributes","fileRepository","FileRepository","loader","createLoader","insertImage","_objectSpread","uploadId","id","Command"],"mappings":";;;;;AAuBO,SAASA,EAAuBC,GAEtC,IAAMC,EAAkBD,EAAME,IAAK,SAAAC,GAAI,OAAIA,EAAKC,QAAS,IAAK,SAE9D,OAAO,IAAIC,OAAJ,aAAAC,OAA0BL,EAAgBM,KAAM,KAAhD,OAUD,SAASC,EAAiBC,GAChC,OAAO,IAAIC,QAAS,SAAEC,EAASC,GAC9B,IAAMC,EAAWJ,EAAMK,aAAc,OAGrCC,MAAOF,GACLG,KAAM,SAAAC,GAAQ,OAAIA,EAASC,SAC3BF,KAAM,SAAAE,GACN,IAAMC,EAAWC,EAAkBF,EAAML,GACnCQ,EAAMF,EAASf,QAAS,SAAU,IAClCkB,EAAQ,SAAAhB,OAAae,GACrBE,EAAO,IAAIC,MAAQN,GAAQI,GAAYnB,KAAMgB,IAEnDR,EAASY,KAETE,MAAO,SAAAC,GAIP,OAAOA,GAAoB,cAAbA,EAAIC,KACjBC,EAA2Bf,GAAWG,KAAML,GAAUc,MAAOb,GAC7DA,EAAQc,OAYN,SAASG,EAAcC,EAAYC,GACzC,SAAMD,EAAWE,kBAAmBD,KAAWA,EAAKjB,aAAc,UAI3DiB,EAAKjB,aAAc,OAAQmB,MAAO,8BACxCF,EAAKjB,aAAc,OAAQmB,MAAO,YAQpC,SAASb,EAAkBF,EAAMgB,GAChC,OAAKhB,EAAKf,KACFe,EAAKf,KACD+B,EAAID,MAAO,4BACfC,EAAID,MAAO,4BAA8B,GAAIE,cAG7C,aAUT,SAASP,EAA2Bf,GACnC,OAAOuB,EAAmBvB,GAAWG,KAAM,SAAAE,GAC1C,IAAMC,EAAWC,EAAkBF,EAAML,GACnCQ,EAAMF,EAASf,QAAS,SAAU,IAClCkB,EAAQ,SAAAhB,OAAae,GAE3B,OAAO,IAAIG,MAAQN,GAAQI,GAAYnB,KAAMgB,MAQ/C,SAASiB,EAAmBvB,GAC3B,OAAO,IAAIH,QAAS,SAAEC,EAASC,GAC9B,IAAMH,EAAQ4B,OAAOC,SAASC,cAAe,OAE7C9B,EAAM+B,iBAAkB,OAAQ,WAC/B,IAAMC,EAASJ,OAAOC,SAASC,cAAe,UAE9CE,EAAOC,MAAQjC,EAAMiC,MACrBD,EAAOE,OAASlC,EAAMkC,OAEtB,IAAMC,EAAMH,EAAOI,WAAY,MAE/BD,EAAIE,UAAWrC,EAAO,EAAG,GAEzBgC,EAAOM,OAAQ,SAAA7B,GAAI,OAAIA,EAAOP,EAASO,GAASN,QAGjDH,EAAM+B,iBAAkB,QAAS,kBAAM5B,MAEvCH,EAAMyB,IAAMrB;;;;OC5FOmC,8JAIpB,WACC,IAAMC,EAASC,KAAKD,OACdnB,EAAamB,EAAOE,QAAQC,IAAK,cACjCC,EAAkBJ,EAAOK,MAAMhB,SAASiB,UAAUC,qBAGxDN,KAAKO,UAAY3B,EAAW4B,kBAAoB5B,EAAW6B,QAASN,0BAUrE,SAASO,GAAU,IAAAC,EAAAX,KACZY,EAAQC,eAASH,EAAQrC,MACzBgC,EAAYL,KAAKD,OAAOK,MAAMhB,SAASiB,UACvCzB,EAAaoB,KAAKD,OAAOE,QAAQC,IAAK,cAUtCY,EAAsBC,OAAOC,YAAaX,EAAUY,iBAE1DL,EAAMM,QAAS,SAAE7C,EAAM8C,GACtB,IAAMhB,EAAkBE,EAAUC,qBAIlC,GAAKa,GAAShB,GAAmBvB,EAAW6B,QAASN,GAAoB,CACxE,IAAMiB,EAAWT,EAAKZ,OAAOK,MAAMiB,oBAAqBlB,GAExDQ,EAAKW,aAAcjD,EAAMyC,EAAqBM,QAE9CT,EAAKW,aAAcjD,EAAMyC,iCAa5B,SAAczC,EAAMkD,EAAYH,GAC/B,IAAMrB,EAASC,KAAKD,OACdyB,EAAiBzB,EAAOE,QAAQC,IAAKuB,QACrCC,EAASF,EAAeG,aAActD,GACtCO,EAAamB,EAAOE,QAAQC,IAAK,cAGjCwB,GAIN9C,EAAWgD,YAAXC,OAA6BN,OAAYO,SAAUJ,EAAOK,KAAMX,UArElBY","file":"js/chunk-01b18244.c4b38a15.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:image/imageutils~ImageUtils} imageUtils\n * @param {module:engine/view/node~Node} node The node to check.\n * @returns {Boolean}\n */\nexport function isLocalImage( imageUtils, node ) {\n\tif ( !imageUtils.isInlineImageView( node ) || !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\nimport { FileRepository } from 'ckeditor5/src/upload';\nimport { Command } from 'ckeditor5/src/core';\nimport { toArray } from 'ckeditor5/src/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~findOptimalInsertionRange} 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 editor = this.editor;\n\t\tconst imageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst selectedElement = editor.model.document.selection.getSelectedElement();\n\n\t\t// TODO: This needs refactoring.\n\t\tthis.isEnabled = imageUtils.isImageAllowed() || imageUtils.isImage( selectedElement );\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 files = toArray( options.file );\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst imageUtils = this.editor.plugins.get( 'ImageUtils' );\n\n\t\t// In case of multiple files, each file (starting from the 2nd) will be inserted at a position that\n\t\t// follows the previous one. That will move the selection and, to stay on the safe side and make sure\n\t\t// all images inherit the same selection attributes, they are collected beforehand.\n\t\t//\n\t\t// Applying these attributes ensures, for instance, that inserting an (inline) image into a link does\n\t\t// not split that link but preserves its continuity.\n\t\t//\n\t\t// Note: Selection attributes that do not make sense for images will be filtered out by insertImage() anyway.\n\t\tconst selectionAttributes = Object.fromEntries( selection.getAttributes() );\n\n\t\tfiles.forEach( ( file, index ) => {\n\t\t\tconst selectedElement = selection.getSelectedElement();\n\n\t\t\t// Inserting of an inline image replace the selected element and make a selection on the inserted image.\n\t\t\t// Therefore inserting multiple inline images requires creating position after each element.\n\t\t\tif ( index && selectedElement && imageUtils.isImage( selectedElement ) ) {\n\t\t\t\tconst position = this.editor.model.createPositionAfter( selectedElement );\n\n\t\t\t\tthis._uploadImage( file, selectionAttributes, position );\n\t\t\t} else {\n\t\t\t\tthis._uploadImage( file, selectionAttributes );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Handles uploading single file.\n\t *\n\t * @private\n\t * @param {File} file\n\t * @param {Object} attributes\n\t * @param {module:engine/model/position~Position} position\n\t */\n\t_uploadImage( file, attributes, position ) {\n\t\tconst editor = this.editor;\n\t\tconst fileRepository = editor.plugins.get( FileRepository );\n\t\tconst loader = fileRepository.createLoader( file );\n\t\tconst imageUtils = editor.plugins.get( 'ImageUtils' );\n\n\t\t// Do not throw when upload adapter is not set. FileRepository will log an error anyway.\n\t\tif ( !loader ) {\n\t\t\treturn;\n\t\t}\n\n\t\timageUtils.insertImage( { ...attributes, uploadId: loader.id }, position );\n\t}\n}\n"],"sourceRoot":""}