@syncfusion/ej2-richtexteditor 29.2.4-795127 → 29.2.4-803054

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28364,6 +28364,9 @@ __decorate$1([
28364
28364
  __decorate$1([
28365
28365
  Property(false)
28366
28366
  ], ImageSettings.prototype, "resizeByPercent", void 0);
28367
+ __decorate$1([
28368
+ Property(false)
28369
+ ], ImageSettings.prototype, "uploadRemoteURLs", void 0);
28367
28370
  /**
28368
28371
  * Configures the audio settings of the RichTextEditor.
28369
28372
  */
@@ -40591,7 +40594,11 @@ class PasteCleanup {
40591
40594
  if (e.args && value !== null && this.parent.editorMode === 'HTML') {
40592
40595
  let file;
40593
40596
  const files = e.args.clipboardData.files;
40594
- if (value.length === 0 || (!isNullOrUndefined(files) && files.length > 0)) {
40597
+ const elm = createElement('p');
40598
+ elm.innerHTML = value;
40599
+ const source = this.findSource(elm);
40600
+ const extractedSRC = this.parent.insertImageSettings.uploadRemoteURLs ? this.extractImageSrcDOM(value) : null;
40601
+ if (value.length === 0 || (!isNullOrUndefined(files) && files.length > 0 && source === 'html')) {
40595
40602
  const htmlRegex = new RegExp(/<\/[a-z][\s\S]*>/i);
40596
40603
  value = e.args.clipboardData.getData('text/plain');
40597
40604
  this.parent.trigger(beforePasteCleanup, { value: value });
@@ -40634,6 +40641,14 @@ class PasteCleanup {
40634
40641
  value = divElement.innerHTML;
40635
40642
  }
40636
40643
  }
40644
+ else if (Array.isArray(extractedSRC) && extractedSRC.length &&
40645
+ this.parent.insertImageSettings.saveUrl && this.parent.insertImageSettings.path) {
40646
+ this.parent.trigger(beforePasteCleanup, { value: value });
40647
+ for (let i = 0; i < extractedSRC.length; i++) {
40648
+ const src = extractedSRC[i];
40649
+ this.fetchImageWithMetadata(src);
40650
+ }
40651
+ }
40637
40652
  else if (value.length > 0) {
40638
40653
  this.parent.trigger(beforePasteCleanup, { value: value });
40639
40654
  this.parent.formatter.editorManager.observer.notify(MS_WORD_CLEANUP, {
@@ -40690,6 +40705,68 @@ class PasteCleanup {
40690
40705
  }
40691
40706
  }
40692
40707
  }
40708
+ findSource(element) {
40709
+ const metaNodes = element.querySelectorAll('meta');
40710
+ for (let i = 0; i < metaNodes.length; i++) {
40711
+ const metaNode = metaNodes[i];
40712
+ const content = metaNode.getAttribute('content');
40713
+ const name = metaNode.getAttribute('name');
40714
+ if (name && name.toLowerCase().indexOf('generator') >= 0 && content && content.toLowerCase().indexOf('microsoft') >= 0) {
40715
+ for (let j = 0; j < PASTE_SOURCE.length; j++) {
40716
+ if (content.toLowerCase().indexOf(PASTE_SOURCE[j]) >= 0) {
40717
+ return PASTE_SOURCE[j];
40718
+ }
40719
+ }
40720
+ }
40721
+ }
40722
+ return 'html';
40723
+ }
40724
+ extractImageSrcDOM(value) {
40725
+ if (!value || typeof value !== 'string') {
40726
+ return null;
40727
+ }
40728
+ const parser = new DOMParser();
40729
+ const doc = parser.parseFromString(value, 'text/html');
40730
+ const images = doc.querySelectorAll('img');
40731
+ if (images.length === 0) {
40732
+ return null;
40733
+ }
40734
+ const srcs = Array.from(images)
40735
+ .map((img) => img.getAttribute('src') || img.src || '')
40736
+ .map((src) => src.trim())
40737
+ .filter((src) => !!src)
40738
+ // Exclude base64/data URLs, blob URLs, and anything containing "id="
40739
+ .filter((src) => {
40740
+ const s = src.toLowerCase();
40741
+ return !s.startsWith('data:') && !s.includes('base64') && !s.startsWith('blob:') && !s.includes('id=');
40742
+ });
40743
+ return srcs.length ? srcs : null;
40744
+ }
40745
+ fetchImageWithMetadata(url) {
40746
+ fetch(url)
40747
+ .then((response) => {
40748
+ if (!response.ok) {
40749
+ console.warn(`Fetch status ${response.status} for: ${url}`);
40750
+ return null;
40751
+ }
40752
+ return response.blob();
40753
+ })
40754
+ .then((blob) => {
40755
+ if (blob) {
40756
+ const filename = this.getFilenameFromUrl(url) || 'downloaded-image.jpg';
40757
+ const mimeType = blob.type || 'image/jpeg';
40758
+ const file = new File([blob], filename, { type: mimeType });
40759
+ const imageElement = this.parent.inputElement.querySelector(`img[src="${url}"]`);
40760
+ this.uploadMethod(file, imageElement);
40761
+ }
40762
+ });
40763
+ }
40764
+ // Helper method to extract filename from URL
40765
+ getFilenameFromUrl(url) {
40766
+ const pathname = new URL(url).pathname;
40767
+ const filename = pathname.substring(pathname.lastIndexOf('/') + 1);
40768
+ return filename || 'image.jpg';
40769
+ }
40693
40770
  splitBreakLine(value) {
40694
40771
  const enterSplitText = value.split('\r\n\r\n');
40695
40772
  let finalText = '';