@syncfusion/ej2-richtexteditor
Version:
Essential JS 2 RichTextEditor component
768 lines (767 loc) • 33.9 kB
JavaScript
import * as EVENTS from '../../common/constant';
import { pasteCleanupGroupingTags } from '../../common/config';
import { createElement, isNullOrUndefined as isNOU, detach, Browser, extend, getUniqueID } from '@syncfusion/ej2-base';
import { convertToBlob } from '../../common/util';
/**
* PasteCleanup common action
*
* @hidden
*/
var PasteCleanupAction = /** @class */ (function () {
function PasteCleanupAction(parent, pasteModel) {
this.parent = parent;
this.pasteModel = pasteModel;
this.addEventListener();
}
PasteCleanupAction.prototype.addEventListener = function () {
this.parent.observer.on(EVENTS.INTERNAL_DESTROY, this.destroy, this);
};
PasteCleanupAction.prototype.removeEventListener = function () {
this.parent.observer.off(EVENTS.INTERNAL_DESTROY, this.destroy);
};
/**
* Updates the paste cleanup object with refreshed editor configuration and callback methods
*
* @param {IPasteModel} updatedPasteModel - The updated paste model with latest configuration
* @returns {void} - This method does not return a value
* @public
* @hidden
*/
PasteCleanupAction.prototype.updatePasteCleanupModel = function (updatedPasteModel) {
this.pasteModel = updatedPasteModel;
};
/**
* Extracts file from clipboard data if available
*
* @param {NotifyArgs} e - The notification arguments containing clipboard data
* @returns {File} The extracted file from clipboard
* @public
* @hidden
*/
PasteCleanupAction.prototype.extractFileFromClipboard = function (e) {
if (!e || !e.args || !e.args.clipboardData ||
e.args.clipboardData.items.length === 0) {
return null;
}
var items = e.args.clipboardData.items;
var file = items[0].getAsFile();
if (file !== null) {
return file;
}
return !isNOU(items[1]) ? items[1].getAsFile() : null;
};
/**
* Splits text by double line breaks and formats it according to editor's enter key configuration
*
* @param {string} value - The text value to be split and formatted
* @returns {string} The formatted text with proper line breaks
* @public
* @hidden
*/
PasteCleanupAction.prototype.splitBreakLine = function (value) {
var enterSplitText = value.split('\r\n\r\n');
var finalText = '';
var startNode = this.getHtmlNode(true);
var endNode = this.getHtmlNode(false);
var isBrFormat = this.pasteModel.enterKey === 'BR';
for (var i = 0; i < enterSplitText.length; i++) {
var content = enterSplitText[i];
var contentWithSpace = this.normalizeSpacesForHtml(content);
var contentWithLineBreak = contentWithSpace.replace(/\r\n|\n/g, '<br>');
if (i === 0) {
if (isBrFormat && (i !== enterSplitText.length - 1 || contentWithLineBreak.endsWith('<br>'))) {
if (i !== enterSplitText.length - 1) {
finalText += (contentWithLineBreak + endNode + endNode);
}
else {
finalText += (contentWithLineBreak + endNode);
}
}
else {
finalText += contentWithLineBreak; // In order to merge the content in current line. No P/Div tag is added.
}
}
else {
if (isBrFormat) {
if (contentWithLineBreak.endsWith('<br>') || (contentWithLineBreak === '' && i === enterSplitText.length - 1)) {
finalText += (contentWithLineBreak + endNode);
}
else if (i === enterSplitText.length - 1) {
finalText += contentWithLineBreak;
}
else {
finalText += (contentWithLineBreak + endNode + endNode);
}
}
else {
if (contentWithLineBreak.trim() === '') {
finalText += '<br>';
}
finalText += startNode + contentWithLineBreak + endNode;
}
}
}
return finalText;
};
/**
* Gets HTML node tag based on enterKey settings and whether it's start or end tag
*
* @param {boolean} isStartTag - Indicates whether to return start tag (true) or end tag (false)
* @returns {string} The HTML node tag string
* @public
* @hidden
*/
PasteCleanupAction.prototype.getHtmlNode = function (isStartTag) {
if (this.pasteModel.enterKey === 'P') {
return isStartTag ? '<p>' : '</p>';
}
else if (this.pasteModel.enterKey === 'DIV') {
return isStartTag ? '<div>' : '</div>';
}
return isStartTag ? '' : '<br>';
};
/**
* Converts spaces and tabs in text to HTML space entities.
*
* @param {string} text - The input text containing spaces and tabs to be converted
* @returns {string} The text with spaces and tabs converted to HTML entities
* @public
* @hidden
*/
PasteCleanupAction.prototype.normalizeSpacesForHtml = function (text) {
var spacedContent = '';
if (text === '') {
return text;
}
var lineBreakSplitText = text.split(' ');
for (var i = 0; i < lineBreakSplitText.length; i++) {
var currentText = lineBreakSplitText[i];
if (currentText === '') {
spacedContent += ' ';
}
else if (currentText === '\t') {
spacedContent += ' ';
}
else {
if (i > 0 && i < lineBreakSplitText.length) {
spacedContent += ' ';
}
spacedContent += currentText;
}
}
spacedContent = spacedContent.replace(/\t/g, ' ');
spacedContent = spacedContent.replace(/ /g, ' ');
return spacedContent;
};
/**
* Converts base64 into file data.
*
* @param {string} base64 - The base64 encoded string to convert
* @param {string} filename - The name for the resulting file
* @returns {File} The converted file object
* @public
* @hidden
*/
PasteCleanupAction.prototype.base64ToFile = function (base64, filename) {
var baseStr = base64.split(',');
var typeStr = baseStr[0].match(/:(.*?);/)[1];
var extension = typeStr.split('/')[1];
var decodeStr = atob(baseStr[1]);
var strLen = decodeStr.length;
var decodeArr = new Uint8Array(strLen);
while (strLen--) {
decodeArr[strLen] = decodeStr.charCodeAt(strLen);
}
if (Browser.isIE || navigator.appVersion.indexOf('Edge') > -1) {
var blob = new Blob([decodeArr], { type: extension });
extend(blob, { name: filename + '.' + (!isNOU(extension) ? extension : '') });
return blob;
}
else {
return new File([decodeArr], filename + '.' + (!isNOU(extension) ? extension : ''), { type: extension });
}
};
/**
* Sets the image opacity to indicate upload in progress.
*
* @param {Element} imgElem - The image element to modify opacity for
* @returns {void} Nothing is returned
* @public
* @hidden
*/
PasteCleanupAction.prototype.setImageOpacity = function (imgElem) {
imgElem.style.opacity = '0.5';
};
/**
* Creates the popup element for upload progress.
*
* @returns {HTMLElement} The created popup element for displaying upload progress
* @public
* @hidden
*/
PasteCleanupAction.prototype.createPopupElement = function () {
var popupEle = createElement('div');
this.pasteModel.rootContainer.appendChild(popupEle);
return popupEle;
};
/**
* Converts base64 image sources to blob URLs.
*
* @param {NodeListOf<HTMLImageElement>} allImgElm - Collection of image elements to process
* @returns {void} Nothing is returned
* @public
* @hidden
*/
PasteCleanupAction.prototype.getBlob = function (allImgElm) {
for (var i = 0; i < allImgElm.length; i++) {
var imgSrc = allImgElm[i].getAttribute('src');
if (!isNOU(imgSrc) && imgSrc.split(',')[0].indexOf('base64') >= 0) {
var blobUrl = URL.createObjectURL(convertToBlob(imgSrc));
allImgElm[i].setAttribute('src', blobUrl);
}
}
};
/**
* Removes Apple-specific line break elements from the HTML content.
*
* @param {HTMLElement} clipBoardElem - The HTML element containing clipboard content to clean
* @returns {HTMLElement} The cleaned HTML element with Apple-specific line breaks removed
* @public
* @hidden
*/
PasteCleanupAction.prototype.cleanAppleClass = function (clipBoardElem) {
var appleClassElem = clipBoardElem.querySelectorAll('br.Apple-interchange-newline');
for (var i = 0; i < appleClassElem.length; i++) {
detach(appleClassElem[i]);
}
return clipBoardElem;
};
/**
* Removes denied tags and attributes as configured by paste cleanup settings.
*
* @param {HTMLElement} clipBoardElem - The HTML element containing clipboard content to clean
* @param {boolean} clean - Flag indicating whether cleanup should be performed
* @returns {HTMLElement} The cleaned HTML element with denied tags and attributes removed
* @public
* @hidden
*/
PasteCleanupAction.prototype.cleanupDeniedTagsAndAttributes = function (clipBoardElem, clean) {
if (this.pasteModel.pasteCleanupSettings.deniedTags !== null) {
clipBoardElem = this.deniedTags(clipBoardElem);
}
if (clean) {
clipBoardElem = this.deniedAttributes(clipBoardElem, clean);
}
else if (this.pasteModel.pasteCleanupSettings.deniedAttrs !== null) {
clipBoardElem = this.deniedAttributes(clipBoardElem, clean);
}
return clipBoardElem;
};
/**
* Removes elements matching denied tags (with or without attribute selectors) from the provided clipboard element.
*
* @param {HTMLElement} clipBoardElem - The HTML element containing clipboard content to process
* @returns {HTMLElement} The cleaned HTML element with denied tags removed
* @public
* @hidden
*/
PasteCleanupAction.prototype.deniedTags = function (clipBoardElem) {
var deniedTags = isNOU(this.pasteModel.pasteCleanupSettings.deniedTags) ? [] : this.pasteModel.pasteCleanupSettings.deniedTags.slice();
deniedTags = this.attributesfilter(deniedTags);
deniedTags = this.tagGrouping(deniedTags);
for (var i = 0; i < deniedTags.length; i++) {
var removableElement = clipBoardElem.querySelectorAll(deniedTags[i]);
for (var j = removableElement.length - 1; j >= 0; j--) {
var elementToRemove = removableElement[j];
var parentElem = elementToRemove.parentNode;
while (elementToRemove.firstChild) {
parentElem.insertBefore(elementToRemove.firstChild, elementToRemove);
}
parentElem.removeChild(elementToRemove);
}
}
return clipBoardElem;
};
/**
* Parses denied tags array and filters attributes, supporting allowed and denied (! prefix) attributes.
*
* @param {string[]} deniedTags - Array of denied tag strings to parse and filter
* @returns {string[]} The filtered array of attribute strings
* @public
* @hidden
*/
PasteCleanupAction.prototype.attributesfilter = function (deniedTags) {
for (var i = 0; i < deniedTags.length; i++) {
var currentDeniedTag = deniedTags[i];
if (currentDeniedTag.split('[').length > 1) {
var userAttributes = currentDeniedTag.split('[')[1].split(']')[0].split(',');
var allowedAttributeArray = [];
var deniedAttributeArray = [];
for (var j = 0; j < userAttributes.length; j++) {
var currentUserAttrs = userAttributes[j];
if (userAttributes[j].indexOf('!') < 0) {
allowedAttributeArray.push(currentUserAttrs.trim());
}
else {
deniedAttributeArray.push(currentUserAttrs.split('!')[1].trim());
}
}
var allowedAttribute = allowedAttributeArray.length > 1 ?
(allowedAttributeArray.join('][')) : (allowedAttributeArray.join());
var deniedAttribute = deniedAttributeArray.length > 1 ?
deniedAttributeArray.join('][') : (deniedAttributeArray.join());
if (deniedAttribute.length > 0) {
var select = allowedAttribute !== '' ? currentDeniedTag.split('[')[0] +
'[' + allowedAttribute + ']' : currentDeniedTag.split('[')[0];
deniedTags[i] = select + ':not([' + deniedAttribute + '])';
}
else {
deniedTags[i] = currentDeniedTag.split('[')[0] + '[' + allowedAttribute + ']';
}
}
}
return deniedTags;
};
/**
* Expands denied tag list by including related tags based on grouping definitions.
*
* @param {string[]} deniedTags - Array of denied tag strings to expand
* @returns {string[]} The expanded array of denied tags including related tags
* @public
* @hidden
*/
PasteCleanupAction.prototype.tagGrouping = function (deniedTags) {
var groupingTags = deniedTags.slice();
var keys = Object.keys(pasteCleanupGroupingTags);
var values = keys.map(function (key) {
return pasteCleanupGroupingTags["" + key];
});
var addTags = [];
for (var i = 0; i < groupingTags.length; i++) {
var currrentGroupTag = groupingTags[i];
var groupIndex = keys.indexOf(currrentGroupTag);
//The value split using '[' because to retrieve the tag name from the user given format which may contain tag with attributes
if (currrentGroupTag.split('[').length > 1) {
currrentGroupTag = currrentGroupTag.split('[')[0].trim();
}
if (keys.indexOf(groupingTags[i]) > -1) {
for (var j = 0; j < values[groupIndex].length; j++) {
if (groupingTags.indexOf(values[groupIndex][j]) < 0 &&
addTags.indexOf(values[groupIndex][j]) < 0) {
addTags.push(values[groupIndex][j]);
}
}
}
}
return deniedTags = deniedTags.concat(addTags);
};
/**
* Removes denied attributes from all elements in the provided clipboard element.
*
* @param {HTMLElement} clipBoardElem - The HTML element containing clipboard content to process
* @param {boolean} clean - Flag indicating whether cleanup should be performed
* @returns {HTMLElement} The cleaned HTML element with denied attributes removed
* @public
* @hidden
*/
PasteCleanupAction.prototype.deniedAttributes = function (clipBoardElem, clean) {
var deniedAttrs = isNOU(this.pasteModel.pasteCleanupSettings.deniedAttrs) ? [] : this.pasteModel.pasteCleanupSettings.deniedAttrs.slice();
if (clean) {
deniedAttrs.push('style');
}
for (var i = 0; i < deniedAttrs.length; i++) {
var currentDeniedAttr = deniedAttrs[i];
var removableAttrElement = clipBoardElem.
querySelectorAll('[' + currentDeniedAttr + ']');
for (var j = 0; j < removableAttrElement.length; j++) {
removableAttrElement[j].removeAttribute(currentDeniedAttr);
}
}
return clipBoardElem;
};
/**
* Filters the inline 'style' attribute on all elements within the clipboard root element, leaving only allowed CSS style properties.
*
* @param {HTMLElement} clipBoardElem - The HTML element containing clipboard content to process
* @returns {HTMLElement} The processed HTML element with filtered style attributes
* @public
* @hidden
*/
PasteCleanupAction.prototype.allowedStyle = function (clipBoardElem) {
var allowedStyleProps = isNOU(this.pasteModel.pasteCleanupSettings.allowedStyleProps) ? [] : this.pasteModel.pasteCleanupSettings.allowedStyleProps.slice();
allowedStyleProps.push('list-style-type', 'list-style');
var elementsWithStyle = clipBoardElem.querySelectorAll('[style]');
for (var i = 0; i < elementsWithStyle.length; i++) {
var currentStyleElem = elementsWithStyle[i];
var allowedStyleValue = '';
var allowedStyleValueArray = [];
var styleValue = currentStyleElem.getAttribute('style').split(';');
for (var k = 0; k < styleValue.length; k++) {
if (allowedStyleProps.indexOf(styleValue[k].split(':')[0].trim()) >= 0) {
allowedStyleValueArray.push(styleValue[k]);
}
}
currentStyleElem.removeAttribute('style');
allowedStyleValue = allowedStyleValueArray.join(';').trim() === '' ?
allowedStyleValueArray.join(';') : allowedStyleValueArray.join(';') + ';';
if (allowedStyleValue) {
currentStyleElem.style.cssText += allowedStyleValue;
}
}
return clipBoardElem;
};
/**
* Adds paste class to images and applies image properties.
*
* @param {HTMLElement} clipBoardElem - The HTML element containing clipboard content with images to process
* @returns {void} Nothing is returned
* @public
* @hidden
*/
PasteCleanupAction.prototype.setImageClassAndProps = function (clipBoardElem) {
var allImg = clipBoardElem.getElementsByTagName('img');
for (var i = 0, len = allImg.length; i < len; i++) {
if (allImg[i].getAttribute('src') !== null) {
allImg[i].className += ' pasteContent_Img';
}
this.setImageProperties(allImg[i]);
}
this.addTempClass(clipBoardElem);
};
/**
* Sets width, height, and min/max styles for inserted images based on editor settings.
*
* @param {HTMLImageElement} allImg - The image element to apply properties to
* @returns {void} Nothing is returned
* @public
* @hidden
*/
PasteCleanupAction.prototype.setImageProperties = function (allImg) {
if (this.pasteModel.insertImageSettings.width !== 'auto') {
allImg.setAttribute('width', this.pasteModel.insertImageSettings.width);
}
if (this.pasteModel.insertImageSettings.minWidth !== '0' && this.pasteModel.insertImageSettings.minWidth !== 0) {
allImg.style.minWidth = this.pasteModel.insertImageSettings.minWidth.toString();
}
if (this.pasteModel.insertImageSettings.maxWidth !== null) {
allImg.style.maxWidth = this.pasteModel.getInsertImgMaxWidth().toString();
}
if (this.pasteModel.insertImageSettings.height !== 'auto') {
allImg.setAttribute('height', this.pasteModel.insertImageSettings.height);
}
if (this.pasteModel.insertImageSettings.minHeight !== '0' && this.pasteModel.insertImageSettings.minHeight !== 0) {
allImg.style.minHeight = this.pasteModel.insertImageSettings.minHeight.toString();
}
if (this.pasteModel.insertImageSettings.maxHeight !== null) {
allImg.style.maxHeight = this.pasteModel.insertImageSettings.maxHeight.toString();
}
};
/**
* Temporarily adds a CSS class to all children of the clipboard element.
*
* @param {HTMLElement} clipBoardElem - The HTML element containing clipboard content to add temporary classes to
* @returns {void} Nothing is returned
* @public
* @hidden
*/
PasteCleanupAction.prototype.addTempClass = function (clipBoardElem) {
var allChild = clipBoardElem.children;
for (var i = 0; i < allChild.length; i++) {
allChild[i].classList.add('pasteContent_RTE');
}
};
/**
* Checks if there is any <picture> element present.
*
* @param {HTMLElement} clipBoardElem - The HTML element to check for picture elements
* @returns {boolean} True if picture element is found, false otherwise
* @public
* @hidden
*/
PasteCleanupAction.prototype.hasPictureElement = function (clipBoardElem) {
return clipBoardElem.getElementsByTagName('picture').length > 0;
};
/**
* Processes all <picture> elements to resolve relative srcset attributes in <source> tags
* using the base URI or the origin of the image source.
*
* @param {HTMLElement} clipBoardElem - The HTML element containing picture elements to process
* @returns {void} Nothing is returned
* @public
* @hidden
*/
PasteCleanupAction.prototype.processPictureElement = function (clipBoardElem) {
var pictureElems = clipBoardElem.querySelectorAll('picture');
var base = this.pasteModel.getDocument().baseURI;
for (var i = 0; i < pictureElems.length; i++) {
var imgElem = pictureElems[i].querySelector('img');
var sourceElems = pictureElems[i].querySelectorAll('source');
if (imgElem && imgElem.getAttribute('src')) {
var srcValue = imgElem.getAttribute('src');
var url = srcValue.indexOf('http') > -1 ? new URL(srcValue) : new URL(srcValue, base);
for (var j = 0; j < sourceElems.length; j++) {
var srcset = sourceElems[j].getAttribute('srcset');
if (srcset) {
if (srcset.indexOf('http') === -1) {
var fullPath = url.origin + srcset;
sourceElems[j].setAttribute('srcset', fullPath);
}
}
}
}
}
};
/**
* Returns true if node has any content (text, images, or table).
*
* @param {HTMLElement} clipBoardElem - The HTML element to check for content
* @returns {boolean} True if the element has content, false otherwise
* @public
* @hidden
*/
PasteCleanupAction.prototype.hasContentToPaste = function (clipBoardElem) {
var hasText = (clipBoardElem.textContent !== '') && (clipBoardElem.textContent.replace(/\u200B/g, '').trim() !== '');
var hasImg = clipBoardElem.getElementsByTagName('img').length > 0;
var hasTable = clipBoardElem.getElementsByTagName('table').length > 0;
return hasText || hasImg || hasTable;
};
/**
* Extracts base64-encoded images from the HTML content and converts them to File objects for upload.
*
* @param {HTMLElement} tempWrapperElem - The HTML element containing base64 images to extract
* @returns {FileInfo[]} Array of FileInfo objects containing the converted file data
* @public
* @hidden
*/
PasteCleanupAction.prototype.collectBase64ImageFiles = function (tempWrapperElem) {
var filesData = [];
if (!isNOU(tempWrapperElem.querySelector('img'))) {
var imgElem = tempWrapperElem.querySelectorAll('img');
var base64Src = [];
var imgName = [];
var uploadImg = [];
for (var i = 0; i < imgElem.length; i++) {
var src = imgElem[i].getAttribute('src');
if (src && src.split(',')[0].indexOf('base64') >= 0) {
base64Src.push(src);
imgName.push(getUniqueID('rte_image'));
uploadImg.push(imgElem[i]);
}
}
var fileList = [];
var currentData = void 0;
for (var i = 0; i < base64Src.length; i++) {
fileList.push(this.base64ToFile(base64Src[i], imgName[i]));
currentData = {
name: fileList[i].name,
rawFile: fileList[i],
size: fileList[i].size,
type: fileList[i].type,
status: '',
validationMessages: { minSize: '', maxSize: '' },
statusCode: '1'
};
filesData.push(currentData);
}
}
return filesData;
};
/**
* Adds appropriate class names to tables in the pasted content for formatting or standardization.
*
* @param {HTMLElement} element - The HTML element containing tables to add classes to
* @param {string} [source] - Optional source parameter for context-specific formatting
* @returns {HTMLElement} The processed HTML element with table classes added
* @public
* @hidden
*/
PasteCleanupAction.prototype.addTableClass = function (element, source) {
var tableElements = element.querySelectorAll('table');
for (var i = 0; i < tableElements.length; i++) {
var table = tableElements[i];
var tableParentElement = table.parentElement;
var isMSTeamsTable = tableParentElement &&
(tableParentElement.nodeName === 'FIGURE');
var hasCustomClass = table.classList.length > 0 &&
table.classList.contains('e-rte-custom-table');
if (hasCustomClass) {
continue; // Skip the custom table class
}
if (this.pasteModel.pasteCleanupSettings.keepFormat && source && !isMSTeamsTable) {
table.classList.add('e-rte-paste-' + source + '-table');
}
else if (!table.classList.contains('e-rte-table')) {
table.classList.add('e-rte-table');
}
// Remove empty next sibling node (if any)
var tableNextSibling = table.nextSibling;
var shouldRemoveNextSibling = isNOU(table.nextElementSibling) &&
tableNextSibling && tableNextSibling.textContent.trim() === '';
if (shouldRemoveNextSibling) {
detach(tableNextSibling);
}
}
return element;
};
/**
* Removes the temporary CSS class from elements and their class attribute if empty.
*
* @returns {void} Nothing is returned
* @public
* @hidden
*/
PasteCleanupAction.prototype.removeTempClass = function () {
var classElm = this.pasteModel.getEditPanel().querySelectorAll('.pasteContent_RTE');
for (var i = 0; i < classElm.length; i++) {
classElm[i].classList.remove('pasteContent_RTE');
if (classElm[i].getAttribute('class') === '') {
classElm[i].removeAttribute('class');
}
}
};
/**
* Handles image cropping and blob-to-base64 conversion for images within the provided element.
*
* @param {HTMLElement} element - The HTML element containing images to be processed.
* @returns {void} Nothing is returned
* @public
* @hidden
*/
PasteCleanupAction.prototype.cropImageHandler = function (element) {
var croppedImgs = element.querySelectorAll('.e-img-cropped');
if (croppedImgs.length > 0) {
this.processCroppedImages(croppedImgs);
}
else {
this.handleBlobOrUpload();
}
};
/**
* Processes all images marked for cropping within the editor element using a for loop.
*
* @param {NodeListOf<HTMLImageElement>} croppedImgs - A NodeList of HTML image elements that are marked for cropping.
* @returns {void} Nothing is returned
* @public
* @hidden
*/
PasteCleanupAction.prototype.processCroppedImages = function (croppedImgs) {
var _this = this;
var _loop_1 = function (i) {
var currentImage = croppedImgs[i];
var src = currentImage.getAttribute('src');
if (src && src.split(',')[0].indexOf('base64') >= 0) {
var cropData_1 = this_1.pasteModel.getCropImageData()[i];
var tempImage_1 = new Image();
tempImage_1.src = src;
tempImage_1.onload = function () {
var wRatio = cropData_1.goalWidth / tempImage_1.naturalWidth;
var hRatio = cropData_1.goalHeight / tempImage_1.naturalHeight;
var cropLeft = cropData_1.cropLength / wRatio;
var cropTop = cropData_1.cropTop / hRatio;
var cropWidth = (cropData_1.goalWidth - cropData_1.cropLength - cropData_1.cropR) / wRatio;
var cropHeight = (cropData_1.goalHeight - cropData_1.cropTop - cropData_1.cropB) / hRatio;
var canvas = document.createElement('canvas');
canvas.width = cropWidth;
canvas.height = cropHeight;
var ctx = canvas.getContext('2d');
if (ctx) {
// Draw the cropped portion of the image onto the canvas
ctx.drawImage(tempImage_1, cropLeft, cropTop, cropWidth, cropHeight, 0, 0, cropWidth, cropHeight);
// Update the image source with the cropped image data
currentImage.setAttribute('src', canvas.toDataURL('image/png'));
currentImage.classList.remove('e-img-cropped');
_this.pasteModel.imageUpload();
if (_this.pasteModel.iframeSettings.enable) {
_this.pasteModel.updateValue();
}
}
};
}
};
var this_1 = this;
for (var i = 0; i < croppedImgs.length; i++) {
_loop_1(i);
}
};
/**
* Handles blob image conversion to base64 (based on clipboard content) or the general image upload/updateValue logic.
*
* @returns {void} Nothing is returned
* @public
* @hidden
*/
PasteCleanupAction.prototype.handleBlobOrUpload = function () {
var _this = this;
var inputElement = this.pasteModel.getEditPanel();
var inputImgs = inputElement.querySelectorAll('img');
var needsBlobConversion = inputImgs.length > 0 &&
inputImgs[0].src.startsWith('blob') &&
!isNOU(this.pasteModel.insertImageSettings.saveUrl) &&
!isNOU(this.pasteModel.insertImageSettings.path);
if (needsBlobConversion) {
// Based on the information in your clipboard, convert blob src 'img' elements to base64 if needed
this.convertBlobToBase64(inputElement);
this.iframeUploadTime = setTimeout(function () {
_this.pasteModel.imageUpload();
if (_this.pasteModel.iframeSettings.enable) {
_this.pasteModel.updateValue();
}
}, 20);
}
else {
this.pasteModel.imageUpload();
if (this.pasteModel.iframeSettings.enable && !this.pasteModel.enableXhtml) {
this.pasteModel.updateValue();
}
}
};
/**
* Converts all <img> elements with a blob URL source inside the provided element to base64.
*
* @param {HTMLElement} element - The HTML element containing image elements to be converted from blob URLs to base64.
* @returns {void} Nothing is returned
* @public
* @hidden
*/
PasteCleanupAction.prototype.convertBlobToBase64 = function (element) {
var imgElem = element.querySelectorAll('img');
var _loop_2 = function (i) {
var imgUrl = imgElem[i].getAttribute('src');
if (imgUrl && imgUrl.startsWith('blob')) {
var tempImage_2 = new Image();
// Once the blob image is loaded, draw it on a canvas and get the base64 string
var onImageLoadEvent_1 = function () {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = tempImage_2.width;
canvas.height = tempImage_2.height;
ctx.drawImage(tempImage_2, 0, 0);
var base64String = canvas.toDataURL('image/png');
// Replace the <img> src with the base64
imgElem[i].src = base64String;
tempImage_2.removeEventListener('load', onImageLoadEvent_1);
};
tempImage_2.src = imgUrl;
tempImage_2.addEventListener('load', onImageLoadEvent_1);
}
};
for (var i = 0; i < imgElem.length; i++) {
_loop_2(i);
}
};
/**
* Cleans up resources when the component is destroyed
*
* @returns {void} - No return value
* @public
*/
PasteCleanupAction.prototype.destroy = function () {
if (this.iframeUploadTime) {
clearTimeout(this.iframeUploadTime);
this.iframeUploadTime = null;
}
this.removeEventListener();
};
return PasteCleanupAction;
}());
export { PasteCleanupAction };