{"version":3,"file":"index.js","sources":["../../../../src/packages/media/media/utils/index.ts"],"sourcesContent":["// TODO => this is NOT a full reimplementation of the existing media helper service, currently\r\n// contains only functions referenced by the TinyMCE editor\r\n// TODO: This should not be done in this way, we need to split this into separate defined helper methods. This is also very specific to TinyMCE, so should be named that way. [NL]\r\n\r\nimport { getProcessedImageUrl } from '@umbraco-cms/backoffice/utils';\r\nimport type { Editor } from '@umbraco-cms/backoffice/external/tinymce';\r\n\r\n/**\r\n * Sizes an image in the editor\r\n * @param editor\r\n * @param imageDomElement\r\n * @param imgUrl\r\n */\r\nexport async function sizeImageInEditor(editor: Editor, imageDomElement: HTMLElement, imgUrl?: string) {\r\n\tconst size = editor.dom.getSize(imageDomElement);\r\n\tconst maxImageSize = editor.options.get('maxImageSize');\r\n\r\n\tif (maxImageSize && maxImageSize > 0) {\r\n\t\tconst newSize = scaleToMaxSize(maxImageSize, size.w, size.h);\r\n\r\n\t\teditor.dom.setAttribs(imageDomElement, { width: Math.round(newSize.width), height: Math.round(newSize.height) });\r\n\r\n\t\t// Images inserted via Media Picker will have a URL we can use for ImageResizer QueryStrings\r\n\t\t// Images pasted/dragged in are not persisted to media until saved & thus will need to be added\r\n\t\tif (imgUrl) {\r\n\t\t\tconst resizedImgUrl = await getProcessedImageUrl(imgUrl, {\r\n\t\t\t\twidth: newSize.width,\r\n\t\t\t\theight: newSize.height,\r\n\t\t\t});\r\n\r\n\t\t\teditor.dom.setAttrib(imageDomElement, 'data-mce-src', resizedImgUrl);\r\n\t\t}\r\n\r\n\t\teditor.execCommand('mceAutoResize', false);\r\n\t}\r\n}\r\n\r\n/**\r\n * Scales an image to the max size\r\n * @param maxSize\r\n * @param width\r\n * @param height\r\n */\r\nexport function scaleToMaxSize(maxSize: number, width: number, height: number) {\r\n\tconst retval = { width, height };\r\n\r\n\tconst maxWidth = maxSize; // Max width for the image\r\n\tconst maxHeight = maxSize; // Max height for the image\r\n\tlet ratio = 0; // Used for aspect ratio\r\n\r\n\t// Check if the current width is larger than the max\r\n\tif (width > maxWidth) {\r\n\t\tratio = maxWidth / width; // get ratio for scaling image\r\n\r\n\t\tretval.width = maxWidth;\r\n\t\tretval.height = height * ratio;\r\n\r\n\t\theight = height * ratio; // Reset height to match scaled image\r\n\t\twidth = width * ratio; // Reset width to match scaled image\r\n\t}\r\n\r\n\t// Check if current height is larger than max\r\n\tif (height > maxHeight) {\r\n\t\tratio = maxHeight / height; // get ratio for scaling image\r\n\r\n\t\tretval.height = maxHeight;\r\n\t\tretval.width = width * ratio;\r\n\t\twidth = width * ratio; // Reset width to match scaled image\r\n\t}\r\n\r\n\treturn retval;\r\n}\r\n\r\n/**\r\n * Uploads blob images to the server\r\n * @param editor\r\n * @param newContent\r\n */\r\nexport async function uploadBlobImages(editor: Editor, newContent?: string) {\r\n\tconst content = newContent ?? editor.getContent();\r\n\r\n\t// Upload BLOB images (dragged/pasted ones)\r\n\t// find src attribute where value starts with `blob:`\r\n\t// search is case-insensitive and allows single or double quotes\r\n\tif (content.search(/src=[\"']blob:.*?[\"']/gi) !== -1) {\r\n\t\tconst data = await editor.uploadImages();\r\n\t\t// Once all images have been uploaded\r\n\t\tdata.forEach((item) => {\r\n\t\t\t// Skip items that failed upload\r\n\t\t\tif (item.status === false) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Select img element\r\n\t\t\tconst img = item.element;\r\n\r\n\t\t\t// Get img src\r\n\t\t\tconst imgSrc = img.getAttribute('src');\r\n\t\t\tconst tmpLocation = sessionStorage.getItem(`tinymce__${imgSrc}`);\r\n\r\n\t\t\t// Select the img & add new attr which we can search for\r\n\t\t\t// When its being persisted in RTE property editor\r\n\t\t\t// To create a media item & delete this tmp one etc\r\n\t\t\teditor.dom.setAttrib(img, 'data-tmpimg', tmpLocation);\r\n\r\n\t\t\t// Resize the image to the max size configured\r\n\t\t\t// NOTE: no imagesrc passed into func as the src is blob://...\r\n\t\t\t// We will append ImageResizing Querystrings on perist to DB with node save\r\n\t\t\tsizeImageInEditor(editor, img);\r\n\t\t});\r\n\r\n\t\t// Get all img where src starts with blob: AND does NOT have a data=tmpimg attribute\r\n\t\t// This is most likely seen as a duplicate image that has already been uploaded\r\n\t\t// editor.uploadImages() does not give us any indiciation that the image been uploaded already\r\n\t\tconst blobImageWithNoTmpImgAttribute = editor.dom.select('img[src^=\"blob:\"]:not([data-tmpimg])');\r\n\r\n\t\t//For each of these selected items\r\n\t\tblobImageWithNoTmpImgAttribute.forEach((imageElement) => {\r\n\t\t\tconst blobSrcUri = editor.dom.getAttrib(imageElement, 'src');\r\n\r\n\t\t\t// Find the same image uploaded (Should be in SessionStorage)\r\n\t\t\t// May already exist in the editor as duplicate image\r\n\t\t\t// OR added to the RTE, deleted & re-added again\r\n\t\t\t// So lets fetch the tempurl out of sessionStorage for that blob URI item\r\n\t\t\tconst tmpLocation = sessionStorage.getItem(`tinymce__${blobSrcUri}`);\r\n\t\t\tif (tmpLocation) {\r\n\t\t\t\tsizeImageInEditor(editor, imageElement);\r\n\t\t\t\teditor.dom.setAttrib(imageElement, 'data-tmpimg', tmpLocation);\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n}\r\n"],"names":["sizeImageInEditor","editor","imageDomElement","imgUrl","size","maxImageSize","newSize","scaleToMaxSize","resizedImgUrl","getProcessedImageUrl","maxSize","width","height","retval","maxWidth","maxHeight","ratio","uploadBlobImages","newContent","item","img","imgSrc","tmpLocation","imageElement","blobSrcUri"],"mappings":";;;;;;AAasB,eAAAA,EAAkBC,GAAgBC,GAA8BC,GAAiB;AACtG,QAAMC,IAAOH,EAAO,IAAI,QAAQC,CAAe,GACzCG,IAAeJ,EAAO,QAAQ,IAAI,cAAc;AAElD,MAAAI,KAAgBA,IAAe,GAAG;AACrC,UAAMC,IAAUC,EAAeF,GAAcD,EAAK,GAAGA,EAAK,CAAC;AAM3D,QAJAH,EAAO,IAAI,WAAWC,GAAiB,EAAE,OAAO,KAAK,MAAMI,EAAQ,KAAK,GAAG,QAAQ,KAAK,MAAMA,EAAQ,MAAM,GAAG,GAI3GH,GAAQ;AACL,YAAAK,IAAgB,MAAMC,EAAqBN,GAAQ;AAAA,QACxD,OAAOG,EAAQ;AAAA,QACf,QAAQA,EAAQ;AAAA,MAAA,CAChB;AAED,MAAAL,EAAO,IAAI,UAAUC,GAAiB,gBAAgBM,CAAa;AAAA,IAAA;AAG7D,IAAAP,EAAA,YAAY,iBAAiB,EAAK;AAAA,EAAA;AAE3C;AAQgB,SAAAM,EAAeG,GAAiBC,GAAeC,GAAgB;AACxE,QAAAC,IAAS,EAAE,OAAAF,GAAO,QAAAC,EAAO,GAEzBE,IAAWJ,GACXK,IAAYL;AAClB,MAAIM,IAAQ;AAGZ,SAAIL,IAAQG,MACXE,IAAQF,IAAWH,GAEnBE,EAAO,QAAQC,GACfD,EAAO,SAASD,IAASI,GAEzBJ,IAASA,IAASI,GAClBL,IAAQA,IAAQK,IAIbJ,IAASG,MACZC,IAAQD,IAAYH,GAEpBC,EAAO,SAASE,GAChBF,EAAO,QAAQF,IAAQK,GACvBL,IAAQA,IAAQK,IAGVH;AACR;AAOsB,eAAAI,EAAiBhB,GAAgBiB,GAAqB;AAM3E,GALgBA,KAAcjB,EAAO,WAAW,GAKpC,OAAO,wBAAwB,MAAM,QACnC,MAAMA,EAAO,aAAa,GAElC,QAAQ,CAACkB,MAAS;AAElB,QAAAA,EAAK,WAAW;AACnB;AAID,UAAMC,IAAMD,EAAK,SAGXE,IAASD,EAAI,aAAa,KAAK,GAC/BE,IAAc,eAAe,QAAQ,YAAYD,CAAM,EAAE;AAK/D,IAAApB,EAAO,IAAI,UAAUmB,GAAK,eAAeE,CAAW,GAKpDtB,EAAkBC,GAAQmB,CAAG;AAAA,EAAA,CAC7B,GAKsCnB,EAAO,IAAI,OAAO,sCAAsC,EAGhE,QAAQ,CAACsB,MAAiB;AACxD,UAAMC,IAAavB,EAAO,IAAI,UAAUsB,GAAc,KAAK,GAMrDD,IAAc,eAAe,QAAQ,YAAYE,CAAU,EAAE;AACnE,IAAIF,MACHtB,EAAkBC,GAAQsB,CAAY,GACtCtB,EAAO,IAAI,UAAUsB,GAAc,eAAeD,CAAW;AAAA,EAC9D,CACA;AAEH;"}